Re: [git:v4l-dvb/for_v3.5] [media] media: mx2_camera: Fix mbus format handling

2012-05-23 Thread javier Martin
Hi Guennadi, Mauro,

 Looks like I have missed this patch, unfortunately, it hasn't been cc'ed
 to me. It would have been better to merge it via my soc-camera tree, also
 because with this merge window there are a couple more changes, that
 affect the generic soc-camera API and the mx2-camera driver in particular.
 So far I don't see anything, what could break here, but if something does
 - we know who will have to fix it;-)

Sorry about that. I usually send patches for mx2-camera to you as well
but this time I missed it. The fact that your name does not appear
when executing 'get_mantainer' doesn't help me to remember either.


 I'm afraid, I get an impression, that your patch breaks support for the
 pass-through mode in the mx2-camera driver. Where previously not natively
 supported formats would be just read in by the camera interface without
 any conversion (see the first entry in the mx27_emma_prp_table[] array),
 you now return an error in mx2_camera_set_bus_param().

I think you are right. It seems I should provide a default for other
mbus formats instead of returning an error. It's good you noticed
because I haven't got any device to test this pass-through mode, so I
try my best to add new functionallity without breaking it.

If I'm write, I'll ask Mauro to revert your patch. Please correct me if I'm 
mistaken.

Is this the way to proceed or should I send a fix on top of it? This
patch is merged in 'for_v3.5', if Mauro reverts it and I send a new
version,  would it be also merged 'for_v3.5' or should it wait for
version 3.6?

Regards.
-- 
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
www.vista-silicon.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 0/2] s5p-mfc: added encoder support for end of stream handling

2012-05-23 Thread Hans Verkuil
Hi Andrzej!

Thanks for the patch, but I do have two questions:

On Tue 22 May 2012 17:33:53 Andrzej Hajda wrote:
 Those patches add end of stream handling for s5p-mfc encoder.
 
 The first patch was sent already to the list as RFC, but the discussion ended
 without any decision.
 This patch adds new v4l2_buffer flag V4L2_BUF_FLAG_EOS. Below short
 description of this change.
 
 s5p_mfc is a mem-to-mem MPEG/H263/H264 encoder and it requires that the last
 incoming frame must be processed differently, it means the information about
 the end of the stream driver should receive NOT LATER than the last
 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE buffer. Common practice
 of sending empty buffer to indicate end-of-stream do not work in such case.
 Setting V4L2_BUF_FLAG_EOS flag for the last V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
 buffer seems to be the most straightforward solution here.
 
 V4L2_BUF_FLAG_EOS flag should be used by application if driver requires it

How will the application know that?

 and it should be set only on V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE buffers.

Why only for this type?

Regards,

Hans

 
 The second patch implements end-of-stream handling in s5p-mfc.
 
 Comments are welcome
 Andrzej Hajda
 
--
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: [git:v4l-dvb/for_v3.5] [media] media: mx2_camera: Fix mbus format handling

2012-05-23 Thread Guennadi Liakhovetski
On Wed, 23 May 2012, javier Martin wrote:

 Hi Guennadi, Mauro,
 
  Looks like I have missed this patch, unfortunately, it hasn't been cc'ed
  to me. It would have been better to merge it via my soc-camera tree, also
  because with this merge window there are a couple more changes, that
  affect the generic soc-camera API and the mx2-camera driver in particular.
  So far I don't see anything, what could break here, but if something does
  - we know who will have to fix it;-)
 
 Sorry about that. I usually send patches for mx2-camera to you as well
 but this time I missed it. The fact that your name does not appear
 when executing 'get_mantainer' doesn't help me to remember either.

No idea whether there is a way to help that script deliver a better 
result, sorry. I certainly would rather avoid listing each soc-camera file 
in MAINTAINERS. I don't think it's a sufficient reason to justify moving 
them all into a separate subdirectory.

  I'm afraid, I get an impression, that your patch breaks support for the
  pass-through mode in the mx2-camera driver. Where previously not natively
  supported formats would be just read in by the camera interface without
  any conversion (see the first entry in the mx27_emma_prp_table[] array),
  you now return an error in mx2_camera_set_bus_param().
 
 I think you are right. It seems I should provide a default for other
 mbus formats instead of returning an error. It's good you noticed
 because I haven't got any device to test this pass-through mode, so I
 try my best to add new functionallity without breaking it.
 
 If I'm write, I'll ask Mauro to revert your patch. Please correct me if I'm 
 mistaken.

s/write/right/

 Is this the way to proceed or should I send a fix on top of it? This
 patch is merged in 'for_v3.5', if Mauro reverts it and I send a new
 version,  would it be also merged 'for_v3.5' or should it wait for
 version 3.6?

I think, it would be better to revert and re-do it for the following 
reason: since neither you nor me can test those pass-through cases, I 
think, it is easier to review patches and try to avoid regressions by 
looking at patches, that take you from a (presumably working) state A step 
by step to a state B, where each patch is seemingly correct, than by 
looking at a patch a that introduces a breakage and b that hopefully 
should fix it back.

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: [git:v4l-dvb/for_v3.5] [media] media: mx2_camera: Fix mbus format handling

2012-05-23 Thread javier Martin
 Is this the way to proceed or should I send a fix on top of it? This
 patch is merged in 'for_v3.5', if Mauro reverts it and I send a new
 version,  would it be also merged 'for_v3.5' or should it wait for
 version 3.6?

 I think, it would be better to revert and re-do it for the following
 reason: since neither you nor me can test those pass-through cases, I
 think, it is easier to review patches and try to avoid regressions by
 looking at patches, that take you from a (presumably working) state A step
 by step to a state B, where each patch is seemingly correct, than by
 looking at a patch a that introduces a breakage and b that hopefully
 should fix it back.

All right. Then Mauro can revert this patch and I'll get my hands on a
new version whenever I have some spare time.
Sorry for the inconvenience.

Regards.
-- 
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
www.vista-silicon.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


[PATCH] gspca-core: Fix buffers staying in queued state after a stream_off

2012-05-23 Thread Hans de Goede
This fixes a regression introduced by commit f7059ea and should be
backported to all supported stable kernels which have this commit.

Signed-off-by: Hans de Goede hdego...@redhat.com
Tested-by: Antonio Ospite osp...@studenti.unina.it
CC: sta...@kernel.org
---
 drivers/media/video/gspca/gspca.c |4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/media/video/gspca/gspca.c 
b/drivers/media/video/gspca/gspca.c
index 137166d..31721ea 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -1653,7 +1653,7 @@ static int vidioc_streamoff(struct file *file, void *priv,
enum v4l2_buf_type buf_type)
 {
struct gspca_dev *gspca_dev = video_drvdata(file);
-   int ret;
+   int i, ret;
 
if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -1678,6 +1678,8 @@ static int vidioc_streamoff(struct file *file, void *priv,
wake_up_interruptible(gspca_dev-wq);
 
/* empty the transfer queues */
+   for (i = 0; i  gspca_dev-nframes; i++)
+   gspca_dev-frame[i].v4l2_buf.flags = ~BUF_ALL_FLAGS;
atomic_set(gspca_dev-fr_q, 0);
atomic_set(gspca_dev-fr_i, 0);
gspca_dev-fr_o = 0;
-- 
1.7.10

--
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: Problems with the gspca_ov519 driver

2012-05-23 Thread Hans de Goede

Hi,

On 05/22/2012 11:02 PM, Antonio Ospite wrote:

snip

I feel I can add a:

Tested-by: Antonio Ospiteosp...@studenti.unina.it


Thanks added to the commit message.


I can backport the change to older kernels and even CC linux-stable if
you think it is appropriate, that's the least I can do to expiate for
knowing about a bug/regression and not hunting its cause hard enough.


Hehe, I've CC-ed sta...@kernel.org on the patch, it should apply cleanly
to older versions, so no backporting is needed.


HdG maybe you could mention f7059ea in the commit message of this fix
if you can confirm the problem was introduced there.


I can confirm that the problem was introduced there and I've added a
reference to that commmit to the commit message thanks for looking
that commit up!

Regards,

Hans
--
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] gspca-core: Fix buffers staying in queued state after a stream_off

2012-05-23 Thread Hans de Goede
This fixes a regression introduced by commit f7059ea and should be
backported to all supported stable kernels which have this commit.

Signed-off-by: Hans de Goede hdego...@redhat.com
Tested-by: Antonio Ospite osp...@studenti.unina.it
CC: sta...@vger.kernel.org
---
 drivers/media/video/gspca/gspca.c |4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/media/video/gspca/gspca.c 
b/drivers/media/video/gspca/gspca.c
index 137166d..31721ea 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -1653,7 +1653,7 @@ static int vidioc_streamoff(struct file *file, void *priv,
enum v4l2_buf_type buf_type)
 {
struct gspca_dev *gspca_dev = video_drvdata(file);
-   int ret;
+   int i, ret;
 
if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -1678,6 +1678,8 @@ static int vidioc_streamoff(struct file *file, void *priv,
wake_up_interruptible(gspca_dev-wq);
 
/* empty the transfer queues */
+   for (i = 0; i  gspca_dev-nframes; i++)
+   gspca_dev-frame[i].v4l2_buf.flags = ~BUF_ALL_FLAGS;
atomic_set(gspca_dev-fr_q, 0);
atomic_set(gspca_dev-fr_i, 0);
gspca_dev-fr_o = 0;
-- 
1.7.10

--
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] gspca-core: Fix buffers staying in queued state after a stream_off

2012-05-23 Thread Hans de Goede

sorry for the spam, I had to resend it because I got the stable
email address wrong.

On 05/23/2012 10:20 AM, Hans de Goede wrote:

This fixes a regression introduced by commit f7059ea and should be
backported to all supported stable kernels which have this commit.

Signed-off-by: Hans de Goedehdego...@redhat.com
Tested-by: Antonio Ospiteosp...@studenti.unina.it
CC: sta...@vger.kernel.org
---
  drivers/media/video/gspca/gspca.c |4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/media/video/gspca/gspca.c 
b/drivers/media/video/gspca/gspca.c
index 137166d..31721ea 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -1653,7 +1653,7 @@ static int vidioc_streamoff(struct file *file, void *priv,
enum v4l2_buf_type buf_type)
  {
struct gspca_dev *gspca_dev = video_drvdata(file);
-   int ret;
+   int i, ret;

if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -1678,6 +1678,8 @@ static int vidioc_streamoff(struct file *file, void *priv,
wake_up_interruptible(gspca_dev-wq);

/* empty the transfer queues */
+   for (i = 0; i  gspca_dev-nframes; i++)
+   gspca_dev-frame[i].v4l2_buf.flags= ~BUF_ALL_FLAGS;
atomic_set(gspca_dev-fr_q, 0);
atomic_set(gspca_dev-fr_i, 0);
gspca_dev-fr_o = 0;

--
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 FIXES FOR 3.5]: gspca radio fixes (updated 2x)

2012-05-23 Thread Hans de Goede

Hi Mauro et al,

This is an updated version of this pull request, including a
regression fix in the gspca core

2nd updated version with amended commit msg for the regression fix,
 correcting the CC email address for linux-stable

Here is a bunch of fixes for gspca and a couple of fixes for
good old radio support :)

The following changes since commit abed623ca59a7d1abed6c4e7459be03e25a90a1e:

  [media] radio-sf16fmi: add support for SF16-FMD (2012-05-20 16:10:05 -0300)

are available in the git repository at:

  git://linuxtv.org/hgoede/gspca.git media-for_v3.5

for you to fetch changes up to 762f29a93eb229279f59bc2b102f194688f8e47e:

  gspca-core: Fix buffers staying in queued state after a stream_off 
(2012-05-23 10:20:24 +0200)


Antonio Ospite (1):
  gspca_ov534: make AGC and AWB controls independent

Hans de Goede (10):
  radio/si470x: Add support for the Axentia ALERT FM USB Receiver
  snd_tea575x: Report correct frequency range for EU/US versus JA models
  snd_tea575x: Make the module using snd_tea575x the fops owner
  snd_tea575x: set_freq: update cached freq to the actual achieved frequency
  bttv: Use btv-has_radio rather then the card info when registering the 
tuner
  bttv: Remove unused needs_tvaudio card variable
  bttv: The Hauppauge 61334 needs the msp3410 to do radio demodulation
  gspca_pac7311: Correct number of controls
  gscpa_sn9c20x: Move clustering of controls to after error checking
  gspca-core: Fix buffers staying in queued state after a stream_off

 drivers/hid/hid-core.c|1 +
 drivers/hid/hid-ids.h |3 +
 drivers/media/radio/radio-maxiradio.c |2 +-
 drivers/media/radio/radio-sf16fmr2.c  |2 +-
 drivers/media/radio/si470x/radio-si470x-usb.c |2 +
 drivers/media/video/bt8xx/bttv-cards.c|   84 ++---
 drivers/media/video/bt8xx/bttv-driver.c   |5 ++
 drivers/media/video/bt8xx/bttv.h  |1 -
 drivers/media/video/bt8xx/bttvp.h |1 +
 drivers/media/video/gspca/gspca.c |4 +-
 drivers/media/video/gspca/ov534.c |   31 +
 drivers/media/video/gspca/pac7311.c   |2 +-
 drivers/media/video/gspca/sn9c20x.c   |   24 ---
 include/sound/tea575x-tuner.h |3 +-
 sound/i2c/other/tea575x-tuner.c   |   21 ---
 sound/pci/es1968.c|2 +-
 sound/pci/fm801.c |4 +-
 17 files changed, 59 insertions(+), 133 deletions(-)

Regards,

Hans
--
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: FM si4712 driver

2012-05-23 Thread Hans Verkuil
On Wed 23 May 2012 11:09:04 Belisko Marek wrote:
 Hi,
 
 I'm planning to start writing driver for si4712 (for GTA04).
 Anybody doing same thing to avoid double work?

There is a driver for the si4713 already. Is the si4712 very different from
the si4713? If it is very similar, then I would suggest that you adapt the
si4713 driver to also support the si4712.

Regards,

Hans
--
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.5] Fix a few compiler warnings

2012-05-23 Thread Hans Verkuil
Hi Mauro,

Some more fixes for compiler warnings. It's for 3.5, but you can also postpone
it to 3.6.

Regards,

Hans

The following changes since commit abed623ca59a7d1abed6c4e7459be03e25a90a1e:

  [media] radio-sf16fmi: add support for SF16-FMD (2012-05-20 16:10:05 -0300)

are available in the git repository at:

  git://linuxtv.org/hverkuil/media_tree.git warnings

for you to fetch changes up to 2e1ee6741f4b5ec308e3d820034634381f5b:

  vino: fix compiler warnings (2012-05-23 11:36:56 +0200)


Hans Verkuil (3):
  saa7146_fops: remove unused variable.
  cx24110: fix compiler warning
  vino: fix compiler warnings

 drivers/media/common/saa7146_fops.c   |5 -
 drivers/media/dvb/frontends/cx24110.c |4 ++--
 drivers/media/video/vino.c|4 ++--
 3 files changed, 4 insertions(+), 9 deletions(-)
--
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/43] rc-core: move timeout and checks to lirc

2012-05-23 Thread David Härdeman
The lirc TX functionality expects the process which writes (TX) data to
the lirc dev to sleep until the actual data has been transmitted by the
hardware.

Since the same timeout calculation is duplicated in more than one driver
(and would have to be duplicated in even more drivers as they gain TX
support), it makes sense to move this timeout calculation to the lirc
layer instead.

Also, the upcoming rc-core layer will not provide the same behaviour, it
will return as soon as all data is buffered in a TX kfifo which lets
userspace get on with its business.

At the same time, centralize some of the sanity checks.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/ir-lirc-codec.c |   33 +
 drivers/media/rc/mceusb.c|   18 --
 drivers/media/rc/rc-loopback.c   |   12 
 3 files changed, 29 insertions(+), 34 deletions(-)

diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 5faba2a..0287716 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -107,6 +107,12 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
unsigned int *txbuf; /* buffer with values to transmit */
ssize_t ret = 0;
size_t count;
+   ktime_t start;
+   s64 towait;
+   unsigned int duration = 0; /* signal duration in us */
+   int i;
+
+   start = ktime_get();
 
lirc = lirc_get_pdata(file);
if (!lirc)
@@ -129,11 +135,30 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
goto out;
}
 
-   if (dev-tx_ir)
-   ret = dev-tx_ir(dev, txbuf, count);
+   if (!dev-tx_ir) {
+   ret = -ENOSYS;
+   goto out;
+   }
+
+   ret = dev-tx_ir(dev, txbuf, (u32)count);
+   if (ret  0)
+   goto out;
+
+   for (i = 0; i  ret; i++)
+   duration += txbuf[i];
 
-   if (ret  0)
-   ret *= sizeof(unsigned);
+   ret *= sizeof(unsigned int);
+
+   /*
+* The lircd gap calculation expects the write function to
+* wait for the actual IR signal to be transmitted before
+* returning.
+*/
+   towait = ktime_us_delta(ktime_add_us(start, duration), ktime_get());
+   if (towait  0) {
+   set_current_state(TASK_INTERRUPTIBLE);
+   schedule_timeout(usecs_to_jiffies(towait));
+   }
 
 out:
kfree(txbuf);
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 84e06d3..6e430dd 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -786,10 +786,6 @@ static int mceusb_tx_ir(struct rc_dev *dev, unsigned 
*txbuf, unsigned count)
int i, ret = 0;
int cmdcount = 0;
unsigned char *cmdbuf; /* MCE command buffer */
-   long signal_duration = 0; /* Singnal length in us */
-   struct timeval start_time, end_time;
-
-   do_gettimeofday(start_time);
 
cmdbuf = kzalloc(sizeof(unsigned) * MCE_CMDBUF_SIZE, GFP_KERNEL);
if (!cmdbuf)
@@ -802,7 +798,6 @@ static int mceusb_tx_ir(struct rc_dev *dev, unsigned 
*txbuf, unsigned count)
 
/* Generate mce packet data */
for (i = 0; (i  count)  (cmdcount  MCE_CMDBUF_SIZE); i++) {
-   signal_duration += txbuf[i];
txbuf[i] = txbuf[i] / MCE_TIME_UNIT;
 
do { /* loop to support long pulses/spaces  127*50us=6.35ms */
@@ -845,19 +840,6 @@ static int mceusb_tx_ir(struct rc_dev *dev, unsigned 
*txbuf, unsigned count)
/* Transmit the command to the mce device */
mce_async_out(ir, cmdbuf, cmdcount);
 
-   /*
-* The lircd gap calculation expects the write function to
-* wait the time it takes for the ircommand to be sent before
-* it returns.
-*/
-   do_gettimeofday(end_time);
-   signal_duration -= (end_time.tv_usec - start_time.tv_usec) +
-  (end_time.tv_sec - start_time.tv_sec) * 100;
-
-   /* delay with the closest number of ticks */
-   set_current_state(TASK_INTERRUPTIBLE);
-   schedule_timeout(usecs_to_jiffies(signal_duration));
-
 out:
kfree(cmdbuf);
return ret ? ret : count;
diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
index fae1615..f9be681 100644
--- a/drivers/media/rc/rc-loopback.c
+++ b/drivers/media/rc/rc-loopback.c
@@ -105,18 +105,9 @@ static int loop_tx_ir(struct rc_dev *dev, unsigned *txbuf, 
unsigned count)
 {
struct loopback_dev *lodev = dev-priv;
u32 rxmask;
-   unsigned total_duration = 0;
unsigned i;
DEFINE_IR_RAW_EVENT(rawir);
 
-   for (i = 0; i  count; i++)
-   total_duration += abs(txbuf[i]);
-
-   if (total_duration == 0) {
-   dprintk(invalid tx data, total duration zero\n);
-   return -EINVAL;
-   }
-
  

[PATCH 09/43] rc-core: add chardev

2012-05-23 Thread David Härdeman
This patch lays the groundwork for adding a rc-core chardev.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-main.c |  211 
 include/media/rc-core.h|6 +
 2 files changed, 196 insertions(+), 21 deletions(-)

diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 8da7701..d7a50b6 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -17,6 +17,7 @@
 #include linux/delay.h
 #include linux/input.h
 #include linux/slab.h
+#include linux/sched.h
 #include linux/device.h
 #include linux/module.h
 #include rc-core-priv.h
@@ -25,6 +26,7 @@
 #define IR_TAB_MIN_SIZE256
 #define IR_TAB_MAX_SIZE8192
 #define RC_DEV_MAX 32
+#define RC_RX_BUFFER_SIZE 1024
 
 /* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */
 #define IR_KEYPRESS_TIMEOUT 250
@@ -34,9 +36,27 @@ static LIST_HEAD(rc_map_list);
 static DEFINE_SPINLOCK(rc_map_lock);
 
 /* Various bits and pieces to keep track of rc devices */
+static unsigned int rc_major;
 static struct rc_dev *rc_dev_table[RC_DEV_MAX];
 static DEFINE_MUTEX(rc_dev_table_mutex);
 
+/**
+ * struct rc_client - keeps track of processes which have opened a rc chardev
+ * @dev: the struct rc_dev which is being controlled
+ * @rxlock: protects the rxfifo
+ * @rxfifo: stores rx events which can be read by the process
+ * @fasync: keeps track of the fasync queue
+ * @node: list of current clients for the rc device (protected by client_lock
+ * in struct rc_dev)
+ */
+struct rc_client {
+   struct rc_dev *dev;
+   spinlock_t rxlock;
+   DECLARE_KFIFO(rxfifo, int, RC_RX_BUFFER_SIZE);
+   struct fasync_struct *fasync;
+   struct list_head node;
+};
+
 static struct rc_map_list *seek_rc_map(const char *name)
 {
struct rc_map_list *map = NULL;
@@ -1041,8 +1061,22 @@ out:
return ret;
 }
 
+/**
+ * rc_dev_release() - release a struct rc_dev
+ * @device: the struct device which corresponds to the struct rc_dev
+ *
+ * This function is called by the driver core when the refcount
+ * for the device reaches zero.
+ */
 static void rc_dev_release(struct device *device)
 {
+   struct rc_dev *dev = to_rc_dev(device);
+
+   if (dev-input_dev)
+   input_free_device(dev-input_dev);
+
+   kfree(dev);
+   module_put(THIS_MODULE);
 }
 
 #define ADD_HOTPLUG_VAR(fmt, val...)   \
@@ -,6 +1145,9 @@ struct rc_dev *rc_allocate_device(void)
dev-input_dev-setkeycode = ir_setkeycode;
input_set_drvdata(dev-input_dev, dev);
 
+   INIT_LIST_HEAD(dev-client_list);
+   spin_lock_init(dev-client_lock);
+
spin_lock_init(dev-rc_map.lock);
spin_lock_init(dev-keylock);
mutex_init(dev-lock);
@@ -1125,18 +1162,18 @@ struct rc_dev *rc_allocate_device(void)
 }
 EXPORT_SYMBOL_GPL(rc_allocate_device);
 
+/**
+ * rc_free_device() - free an allocated struct rc_dev
+ * @dev:   the struct rc_dev to free
+ *
+ * This function is used by drivers to free a struct rc_dev which has
+ * been allocated with rc_allocate_device(). It must not be used
+ * after rc_register_device() has been successfully called.
+ */
 void rc_free_device(struct rc_dev *dev)
 {
-   if (!dev)
-   return;
-
-   if (dev-input_dev)
-   input_free_device(dev-input_dev);
-
-   put_device(dev-dev);
-
-   kfree(dev);
-   module_put(THIS_MODULE);
+   if (dev)
+   put_device(dev-dev);
 }
 EXPORT_SYMBOL_GPL(rc_free_device);
 
@@ -1183,6 +1220,7 @@ int rc_register_device(struct rc_dev *dev)
return -ENFILE;
 
dev-minor = i;
+   dev-dev.devt = MKDEV(rc_major, dev-minor);
dev_set_name(dev-dev, rc%u, dev-minor);
dev_set_drvdata(dev-dev, dev);
 
@@ -1251,6 +1289,7 @@ int rc_register_device(struct rc_dev *dev)
goto out_raw;
}
 
+   dev-exist = true;
mutex_unlock(dev-lock);
 
IR_dprintk(1, Registered rc%u (driver: %s, remote: %s, mode %s)\n,
@@ -1282,13 +1321,24 @@ EXPORT_SYMBOL_GPL(rc_register_device);
 
 void rc_unregister_device(struct rc_dev *dev)
 {
+   struct rc_client *client;
+
if (!dev)
return;
 
+   mutex_lock(dev-lock);
+   dev-exist = false;
+   mutex_unlock(dev-lock);
+
mutex_lock(rc_dev_table_mutex);
rc_dev_table[dev-minor] = NULL;
mutex_unlock(rc_dev_table_mutex);
 
+   spin_lock(dev-client_lock);
+   list_for_each_entry(client, dev-client_list, node)
+   kill_fasync(client-fasync, SIGIO, POLL_HUP);
+   spin_unlock(dev-client_lock);
+
del_timer_sync(dev-timer_keyup);
 
if (dev-driver_type == RC_DRIVER_IR_RAW)
@@ -1301,34 +1351,153 @@ void rc_unregister_device(struct rc_dev *dev)
input_unregister_device(dev-input_dev);
dev-input_dev = NULL;
 
-   device_del(dev-dev);
-
-   rc_free_device(dev);
+   

[PATCH 04/43] rc-core: use the full 32 bits for NEC scancodes

2012-05-23 Thread David Härdeman
Using the full 32 bits for all kinds of NEC scancodes simplifies rc-core
and the nec decoder without any loss of functionality.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/dvb/dvb-usb/af9015.c   |   22 ++
 drivers/media/dvb/dvb-usb/af9035.c   |   20 +++-
 drivers/media/dvb/dvb-usb/az6007.c   |   16 
 drivers/media/dvb/dvb-usb/it913x.c   |   15 ++-
 drivers/media/dvb/dvb-usb/rtl28xxu.c |   21 -
 drivers/media/rc/ir-nec-decoder.c|   28 
 include/media/rc-map.h   |   11 +--
 7 files changed, 36 insertions(+), 97 deletions(-)

diff --git a/drivers/media/dvb/dvb-usb/af9015.c 
b/drivers/media/dvb/dvb-usb/af9015.c
index bd47e68..4733044 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -1046,7 +1046,8 @@ static int af9015_rc_query(struct dvb_usb_device *d)
if ((priv-rc_repeat != buf[6] || buf[0]) 
!memcmp(buf[12], priv-rc_last, 4)) {
deb_rc(%s: key repeated\n, __func__);
-   rc_keydown(d-rc_dev, RC_TYPE_NEC, priv-rc_keycode, 0);
+   rc_keydown(d-rc_dev, RC_TYPE_NEC,
+  RC_SCANCODE_NEC32(priv-rc_keycode), 0);
priv-rc_repeat = buf[6];
return ret;
}
@@ -1063,21 +1064,10 @@ static int af9015_rc_query(struct dvb_usb_device *d)
 
/* Remember this key */
memcpy(priv-rc_last, buf[12], 4);
-   if (buf[14] == (u8) ~buf[15]) {
-   if (buf[12] == (u8) ~buf[13]) {
-   /* NEC */
-   priv-rc_keycode = buf[12]  8 | buf[14];
-   } else {
-   /* NEC extended*/
-   priv-rc_keycode = buf[12]  16 |
-   buf[13]  8 | buf[14];
-   }
-   } else {
-   /* 32 bit NEC */
-   priv-rc_keycode = buf[12]  24 | buf[13]  16 |
-   buf[14]  8 | buf[15];
-   }
-   rc_keydown(d-rc_dev, RC_TYPE_NEC, priv-rc_keycode, 0);
+   priv-rc_keycode = buf[12]  24 | buf[13]  16 |
+  buf[14]  8  | buf[15];
+   rc_keydown(d-rc_dev, RC_TYPE_NEC,
+  RC_SCANCODE_NEC32(priv-rc_keycode), 0);
} else {
deb_rc(%s: no key press\n, __func__);
/* Invalidate last keypress */
diff --git a/drivers/media/dvb/dvb-usb/af9035.c 
b/drivers/media/dvb/dvb-usb/af9035.c
index c000feb..42094e1 100644
--- a/drivers/media/dvb/dvb-usb/af9035.c
+++ b/drivers/media/dvb/dvb-usb/af9035.c
@@ -311,24 +311,10 @@ static int af9035_rc_query(struct dvb_usb_device *d)
 
ret = af9035_ctrl_msg(d-udev, req);
if (ret  0)
-   goto err;
-
-   if ((b[2] + b[3]) == 0xff) {
-   if ((b[0] + b[1]) == 0xff) {
-   /* NEC */
-   key = b[0]  8 | b[2];
-   } else {
-   /* ext. NEC */
-   key = b[0]  16 | b[1]  8 | b[2];
-   }
-   } else {
-   key = b[0]  24 | b[1]  16 | b[2]  8 | b[3];
-   }
-
-   rc_keydown(d-rc_dev, RC_TYPE_NEC, key, 0);
+   return 0;
 
-err:
-   /* ignore errors */
+   key = b[0]  24 | b[1]  16 | b[2]  8 | b[3];
+   rc_keydown(d-rc_dev, RC_TYPE_NEC, RC_SCANCODE_NEC32(key), 0);
return 0;
 }
 
diff --git a/drivers/media/dvb/dvb-usb/az6007.c 
b/drivers/media/dvb/dvb-usb/az6007.c
index 1e26863..1e5888f 100644
--- a/drivers/media/dvb/dvb-usb/az6007.c
+++ b/drivers/media/dvb/dvb-usb/az6007.c
@@ -204,18 +204,10 @@ static int az6007_rc_query(struct dvb_usb_device *d)
if (st-data[1] == 0x44)
return 0;
 
-   if ((st-data[3] ^ st-data[4]) == 0xff) {
-   if ((st-data[1] ^ st-data[2]) == 0xff)
-   code = RC_SCANCODE_NEC(st-data[1], st-data[3]);
-   else
-   code = RC_SCANCODE_NECX(st-data[1]  8 | st-data[2],
-   st-data[3]);
-   } else {
-   code = RC_SCANCODE_NEC32(st-data[1]  24 |
-st-data[2]  16 |
-st-data[3]  8  |
-st-data[4]);
-   }
+   code = RC_SCANCODE_NEC32(st-data[1]  24 |
+st-data[2]  16 |
+st-data[3]  8  |
+st-data[4]);
 
rc_keydown(d-rc_dev, RC_TYPE_NEC, code, st-data[5]);
 
diff --git a/drivers/media/dvb/dvb-usb/it913x.c 
b/drivers/media/dvb/dvb-usb/it913x.c
index 2c3c400..59d3f07 100644
--- 

[PATCH 00/43] rc-core: feature parity with LIRC

2012-05-23 Thread David Härdeman
The following patchset provides most of the features necessary for parity with
the LIRC subsystem that rc-core is intended to replace.

Most importantly, a chardev is provided which can be used to control RC hardware
using read (RX), write (TX) and ioctl (setting RX/TX parameters).

The patchset still needs further testing and I am well aware that patches will
be necessary to the current userspace tools as well. However, I'd like to get
the discussion started on whether the API needs any changes before I invest more
time in testing and patches to other tools.

Code review is welcome but the most important part is the userspace-kernel
interface (i.e. the read/write/ioctl interface).

Comments?

---

David Härdeman (43):
  rc-core: move timeout and checks to lirc
  rc-core: add separate defines for protocol bitmaps and numbers
  rc-core: don't throw away protocol information
  rc-core: use the full 32 bits for NEC scancodes
  rc-core: merge rc5 and streamzap decoders
  rc-core: rename ir_input_class to rc_class
  rc-core: initialize rc-core earlier if built-in
  rc-core: use a device table rather than an atomic number
  rc-core: add chardev
  rc-core: allow chardev to be read
  mceusb: remove pointless kmalloc
  redrat: cleanup debug functions
  rc-core: use a kfifo for TX data
  rc-core: allow chardev to be written
  rc-core: add ioctl support to the rc chardev
  rc-core: add an ioctl for getting IR RX settings
  rc-loopback: add RCIOCGIRRX ioctl support
  rc-core: add an ioctl for setting IR RX settings
  rc-loopback: add RCIOCSIRRX ioctl support
  rc-core: add an ioctl for getting IR TX settings
  rc-loopback: add RCIOCGIRTX ioctl support
  rc-core: add an ioctl for setting IR TX settings
  rc-loopback: add RCIOCSIRTX ioctl support
  rc-core: leave the internals of rc_dev alone
  rc-core: prepare for multiple keytables
  rc-core: do not take mutex on rc_dev registration
  rc-core: make the keytable of rc_dev an array
  rc-core: add ioctls for adding/removing keytables from userspace
  rc-core: remove redundant spinlock
  rc-core: make keytable RCU-friendly
  rc-core: allow empty keymaps
  rc-core: split IR raw handling to a separate module
  rc-ir-raw: simplify locking
  rc-core: rename mutex
  rc-ir-raw: atomic reads of protocols
  rc-core: fix various sparse warnings
  rc-core: don't report scancodes via input devices
  rc-ir-raw: add various rc_events
  rc-core: use struct rc_event to signal TX events from userspace
  rc-core: use struct rc_event for all rc communication
  rc-core: add keytable events
  rc-core: move remaining keytable functions
  rc-core: make rc-core.h userspace friendly


 Documentation/ioctl/ioctl-number.txt   |1 
 drivers/media/dvb/dm1105/dm1105.c  |3 
 drivers/media/dvb/dvb-usb/Kconfig  |2 
 drivers/media/dvb/dvb-usb/af9015.c |   38 -
 drivers/media/dvb/dvb-usb/af9035.c |   25 
 drivers/media/dvb/dvb-usb/anysee.c |4 
 drivers/media/dvb/dvb-usb/az6007.c |   19 
 drivers/media/dvb/dvb-usb/dib0700_core.c   |   11 
 drivers/media/dvb/dvb-usb/dib0700_devices.c|  156 +-
 drivers/media/dvb/dvb-usb/dvb-usb-remote.c |   11 
 drivers/media/dvb/dvb-usb/dvb-usb.h|4 
 drivers/media/dvb/dvb-usb/it913x.c |   24 
 drivers/media/dvb/dvb-usb/lmedm04.c|   11 
 drivers/media/dvb/dvb-usb/pctv452e.c   |   15 
 drivers/media/dvb/dvb-usb/rtl28xxu.c   |   32 
 drivers/media/dvb/dvb-usb/technisat-usb2.c |   17 
 drivers/media/dvb/dvb-usb/ttusb2.c |4 
 drivers/media/dvb/mantis/mantis_input.c|2 
 drivers/media/dvb/siano/Kconfig|2 
 drivers/media/dvb/siano/smsir.c|   13 
 drivers/media/dvb/siano/smsir.h|2 
 drivers/media/dvb/ttpci/budget-ci.c|7 
 drivers/media/rc/Kconfig   |   66 +
 drivers/media/rc/Makefile  |4 
 drivers/media/rc/ati_remote.c  |   18 
 drivers/media/rc/ene_ir.c  |   69 -
 drivers/media/rc/ene_ir.h  |9 
 drivers/media/rc/fintek-cir.c  |   30 
 drivers/media/rc/gpio-ir-recv.c|   11 
 drivers/media/rc/imon.c|   45 -
 drivers/media/rc/ir-jvc-decoder.c  |   54 -
 drivers/media/rc/ir-lirc-codec.c   |  191 ++-
 drivers/media/rc/ir-mce_kbd-decoder.c  |   38 -
 drivers/media/rc/ir-nec-decoder.c  |   93 +
 drivers/media/rc/ir-raw.c  |  374 --
 drivers/media/rc/ir-rc5-decoder.c  |   94 +
 drivers/media/rc/ir-rc5-sz-decoder.c   |  154 --
 drivers/media/rc/ir-rc6-decoder.c  |  102 +-
 

[PATCH 35/43] rc-ir-raw: atomic reads of protocols

2012-05-23 Thread David Härdeman
Use atomic reads to avoid having to take a mutex when getting
the bitmask of supported protocols.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-core-priv.h |2 +-
 drivers/media/rc/rc-ir-raw.c|   12 
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index b0e1686..54af19a 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -25,7 +25,7 @@
 struct ir_raw_handler {
struct list_head list;
 
-   u64 protocols; /* which are handled by this handler */
+   unsigned protocols; /* which are handled by this handler */
int (*decode)(struct rc_dev *dev, struct ir_raw_event event);
 
/* These two should only be used by the lirc decoder */
diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index 42769b4..88a2932 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -29,7 +29,7 @@ static LIST_HEAD(ir_raw_client_list);
 static LIST_HEAD(ir_raw_handler_list);
 
 /* protocols supported by the currently loaded decoders */
-static u64 available_protocols;
+static atomic_t available_protocols = ATOMIC_INIT(0);
 
 static int ir_raw_event_thread(void *data)
 {
@@ -211,11 +211,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_handle);
 static u64
 ir_raw_get_allowed_protocols(struct rc_dev *dev)
 {
-   u64 protocols;
-   mutex_lock(ir_raw_mutex);
-   protocols = available_protocols;
-   mutex_unlock(ir_raw_mutex);
-   return protocols;
+   return atomic_read(available_protocols);
 }
 
 /*
@@ -305,7 +301,7 @@ int ir_raw_handler_register(struct ir_raw_handler 
*ir_raw_handler)
if (ir_raw_handler-raw_register)
list_for_each_entry_rcu(raw, ir_raw_client_list, list)
ir_raw_handler-raw_register(raw-dev);
-   available_protocols |= ir_raw_handler-protocols;
+   atomic_set_mask(ir_raw_handler-protocols, available_protocols);
mutex_unlock(ir_raw_mutex);
synchronize_rcu();
 
@@ -322,7 +318,7 @@ void ir_raw_handler_unregister(struct ir_raw_handler 
*ir_raw_handler)
if (ir_raw_handler-raw_unregister)
list_for_each_entry_rcu(raw, ir_raw_client_list, list)
ir_raw_handler-raw_unregister(raw-dev);
-   available_protocols = ~ir_raw_handler-protocols;
+   atomic_clear_mask(ir_raw_handler-protocols, available_protocols);
mutex_unlock(ir_raw_mutex);
synchronize_rcu();
 }

--
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 29/43] rc-core: remove redundant spinlock

2012-05-23 Thread David Härdeman
Remove a redundant spinlock from struct rc_map.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-keytable.c |   43 +---
 include/media/rc-core.h|4 ++--
 include/media/rc-map.h |1 -
 3 files changed, 20 insertions(+), 28 deletions(-)

diff --git a/drivers/media/rc/rc-keytable.c b/drivers/media/rc/rc-keytable.c
index bdb60f4..eb48358 100644
--- a/drivers/media/rc/rc-keytable.c
+++ b/drivers/media/rc/rc-keytable.c
@@ -335,7 +335,7 @@ static int ir_setkeycode(struct input_dev *idev,
 
entry.keycode = ke-keycode;
 
-   spin_lock_irqsave(rc_map-lock, flags);
+   spin_lock_irqsave(kt-lock, flags);
 
if (ke-flags  INPUT_KEYMAP_BY_INDEX) {
index = ke-index;
@@ -391,7 +391,7 @@ static int ir_setkeycode(struct input_dev *idev,
*old_keycode = ir_update_mapping(kt, rc_map, index, 
ke-keycode);
 
 out:
-   spin_unlock_irqrestore(rc_map-lock, flags);
+   spin_unlock_irqrestore(kt-lock, flags);
return retval;
 }
 
@@ -495,7 +495,7 @@ static int ir_getkeycode(struct input_dev *idev,
unsigned int index;
int retval;
 
-   spin_lock_irqsave(rc_map-lock, flags);
+   spin_lock_irqsave(kt-lock, flags);
 
if (ke-flags  INPUT_KEYMAP_BY_INDEX) {
index = ke-index;
@@ -564,7 +564,7 @@ static int ir_getkeycode(struct input_dev *idev,
retval = 0;
 
 out:
-   spin_unlock_irqrestore(rc_map-lock, flags);
+   spin_unlock_irqrestore(kt-lock, flags);
return retval;
 }
 
@@ -574,25 +574,15 @@ static u32 rc_get_keycode(struct rc_keytable *kt,
struct rc_map *rc_map;
unsigned int keycode = KEY_RESERVED;
unsigned int index;
-   unsigned long flags;
 
rc_map = kt-rc_map;
if (!rc_map)
return KEY_RESERVED;
 
-   spin_lock_irqsave(rc_map-lock, flags);
-
index = ir_lookup_by_scancode(rc_map, protocol, scancode);
if (index  rc_map-len)
keycode = rc_map-scan[index].keycode;
 
-   spin_unlock_irqrestore(rc_map-lock, flags);
-
-   if (keycode != KEY_RESERVED)
-   IR_dprintk(1, %s: protocol 0x%04x scancode 0x%08llx keycode 
0x%02x\n,
-  kt-dev-input_name, protocol,
-  (unsigned long long)scancode, keycode);
-
return keycode;
 }
 
@@ -613,13 +603,17 @@ u32 rc_g_keycode_from_table(struct rc_dev *dev,
 {
struct rc_keytable *kt;
unsigned int keycode = KEY_RESERVED;
+   unsigned long flags;
 
/* FIXME: This entire function is a hack. Remove it */
rcu_read_lock();
kt = rcu_dereference(dev-keytables[0]);
if (!kt)
goto out;
+
+   spin_lock_irqsave(kt-lock, flags);
keycode = rc_get_keycode(kt, protocol, scancode);
+   spin_unlock_irqrestore(kt-lock, flags);
 
 out:
rcu_read_unlock();
@@ -633,7 +627,7 @@ EXPORT_SYMBOL_GPL(rc_g_keycode_from_table);
  * @sync:  whether or not to call input_sync
  *
  * This function is used internally to release a keypress, it must be
- * called with keylock held.
+ * called with kt-lock held.
  */
 static void rc_do_keyup(struct rc_keytable *kt, bool sync)
 {
@@ -658,9 +652,9 @@ void rc_keytable_keyup(struct rc_keytable *kt)
 {
unsigned long flags;
 
-   spin_lock_irqsave(kt-keylock, flags);
+   spin_lock_irqsave(kt-lock, flags);
rc_do_keyup(kt, true);
-   spin_unlock_irqrestore(kt-keylock, flags);
+   spin_unlock_irqrestore(kt-lock, flags);
 }
 
 /**
@@ -685,10 +679,10 @@ static void rc_timer_keyup(unsigned long cookie)
 * to allow the input subsystem to do its auto-repeat magic or
 * a keyup event might follow immediately after the keydown.
 */
-   spin_lock_irqsave(kt-keylock, flags);
+   spin_lock_irqsave(kt-lock, flags);
if (time_is_before_eq_jiffies(kt-keyup_jiffies))
rc_do_keyup(kt, true);
-   spin_unlock_irqrestore(kt-keylock, flags);
+   spin_unlock_irqrestore(kt-lock, flags);
 }
 
 /**
@@ -703,7 +697,7 @@ void rc_keytable_repeat(struct rc_keytable *kt)
 {
unsigned long flags;
 
-   spin_lock_irqsave(kt-keylock, flags);
+   spin_lock_irqsave(kt-lock, flags);
 
input_event(kt-idev, EV_MSC, MSC_SCAN, kt-last_scancode);
input_sync(kt-idev);
@@ -715,7 +709,7 @@ void rc_keytable_repeat(struct rc_keytable *kt)
mod_timer(kt-timer_keyup, kt-keyup_jiffies);
 
 out:
-   spin_unlock_irqrestore(kt-keylock, flags);
+   spin_unlock_irqrestore(kt-lock, flags);
 }
 
 /**
@@ -736,7 +730,7 @@ void rc_keytable_keydown(struct rc_keytable *kt, enum 
rc_type protocol,
u32 keycode;
bool new_event;
 
-   spin_lock_irqsave(kt-keylock, flags);
+   spin_lock_irqsave(kt-lock, flags);
 
keycode = rc_get_keycode(kt, protocol, scancode);
new_event = !kt-keypressed || kt-last_protocol != 

[PATCH 26/43] rc-core: do not take mutex on rc_dev registration

2012-05-23 Thread David Härdeman
Change the rc_register_device() code so that it isn't necessary to hold any
mutex. When device_add() is called, the norm is that the device should
actually be ready for use.

Holding the mutex is a recipe for deadlocks as (for example) calling
input_register_device() is quite likely to end up in a call to
input_dev-open() which might take the same mutex (to update the user
count, see later patches).

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-main.c |   95 ++--
 include/media/rc-core.h|3 -
 2 files changed, 40 insertions(+), 58 deletions(-)

diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 83ea507..620cd8d 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -214,8 +214,8 @@ static struct {
  * It returns the protocol names of supported protocols.
  * Enabled protocols are printed in brackets.
  *
- * dev-lock is taken to guard against races between device
- * registration, store_protocols and show_protocols.
+ * dev-lock is taken to guard against races between store_protocols
+ * and show_protocols.
  */
 static ssize_t show_protocols(struct device *device,
  struct device_attribute *mattr, char *buf)
@@ -276,8 +276,8 @@ static ssize_t show_protocols(struct device *device,
  * Returns -EINVAL if an invalid protocol combination or unknown protocol name
  * is used, otherwise @len.
  *
- * dev-lock is taken to guard against races between device
- * registration, store_protocols and show_protocols.
+ * dev-lock is taken to guard against races between store_protocols and
+ * show_protocols.
  */
 static ssize_t store_protocols(struct device *device,
   struct device_attribute *mattr,
@@ -492,17 +492,14 @@ int rc_register_device(struct rc_dev *dev)
if (rc)
return rc;
 
-   for (i = 0; i  ARRAY_SIZE(rc_dev_table); i++) {
-   if (!rc_dev_table[i]) {
-   rc_dev_table[i] = dev;
+   for (i = 0; i  ARRAY_SIZE(rc_dev_table); i++)
+   if (!rc_dev_table[i])
break;
-   }
-   }
-
-   mutex_unlock(rc_dev_table_mutex);
 
-   if (i = ARRAY_SIZE(rc_dev_table))
-   return -ENFILE;
+   if (i = ARRAY_SIZE(rc_dev_table)) {
+   rc = -ENFILE;
+   goto out;
+   }
 
dev-minor = i;
dev-dev.devt = MKDEV(rc_major, dev-minor);
@@ -512,35 +509,9 @@ int rc_register_device(struct rc_dev *dev)
if (dev-tx_ir) {
rc = kfifo_alloc(dev-txfifo, RC_TX_KFIFO_SIZE, GFP_KERNEL);
if (rc)
-   goto out_minor;
-   }
-
-   /*
-* Take the lock here, as the device sysfs node will appear
-* when device_add() is called, which may trigger an ir-keytable udev
-* rule, which will in turn call show_protocols and access either
-* dev-rc_map.rc_type or dev-raw-enabled_protocols before it has
-* been initialized.
-*/
-   mutex_lock(dev-lock);
-
-   dev-kt = rc_keytable_create(dev, dev-map_name);
-   if (!dev-kt) {
-   rc = -ENOMEM;
-   goto out_unlock;
+   goto out;
}
 
-   rc = device_add(dev-dev);
-   if (rc)
-   goto out_keytable;
-
-   path = kobject_get_path(dev-dev.kobj, GFP_KERNEL);
-   printk(KERN_INFO %s: %s as %s\n,
-   dev_name(dev-dev),
-   dev-input_name ? dev-input_name : Unspecified device,
-   path ? path : N/A);
-   kfree(path);
-
if (dev-driver_type == RC_DRIVER_IR_RAW) {
/* Load raw decoders, if they aren't already */
if (!raw_init) {
@@ -550,7 +521,7 @@ int rc_register_device(struct rc_dev *dev)
}
rc = ir_raw_event_register(dev);
if (rc  0)
-   goto out_dev;
+   goto out_kfifo;
}
 
if (dev-change_protocol) {
@@ -559,29 +530,41 @@ int rc_register_device(struct rc_dev *dev)
goto out_raw;
}
 
+   rc_dev_table[i] = dev;
dev-exist = true;
-   mutex_unlock(dev-lock);
 
-   IR_dprintk(1, Registered rc%u (driver: %s, remote: %s, mode %s)\n,
-  dev-minor,
-  dev-driver_name ? dev-driver_name : unknown,
-  dev-map_name ? dev-map_name : unknown,
-  dev-driver_type == RC_DRIVER_IR_RAW ? raw : cooked);
+   /* Once device_add is called, userspace might access e.g. sysfs files */
+   rc = device_add(dev-dev);
+   if (rc)
+   goto out_chardev;
+
+   dev-kt = rc_keytable_create(dev, dev-map_name);
+   if (!dev-kt) {
+   rc = -ENOMEM;
+   goto out_device;
+   }
+
+   mutex_unlock(rc_dev_table_mutex);
+
+   path = 

[PATCH 28/43] rc-core: add ioctls for adding/removing keytables from userspace

2012-05-23 Thread David Härdeman
As all the basics are now in place, we can finally add the ioctls
for adding/removing keytables from userspace.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-core-priv.h |3 +
 drivers/media/rc/rc-keytable.c  |6 ++-
 drivers/media/rc/rc-main.c  |   82 +++
 include/media/rc-core.h |   27 -
 4 files changed, 107 insertions(+), 11 deletions(-)

diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index 7aaa1bf..8006c2e 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -156,7 +156,8 @@ void rc_keytable_keyup(struct rc_keytable *kt);
 void rc_keytable_repeat(struct rc_keytable *kt);
 void rc_keytable_keydown(struct rc_keytable *kt, enum rc_type protocol,
 u64 scancode, u8 toggle, bool autokeyup);
-struct rc_keytable *rc_keytable_create(struct rc_dev *dev, const char 
*map_name);
+struct rc_keytable *rc_keytable_create(struct rc_dev *dev, const char *name,
+  const char *map_name);
 void rc_keytable_destroy(struct rc_keytable *kt);
 
 /* Only to be used by rc-core and ir-lirc-codec */
diff --git a/drivers/media/rc/rc-keytable.c b/drivers/media/rc/rc-keytable.c
index f422a3b..bdb60f4 100644
--- a/drivers/media/rc/rc-keytable.c
+++ b/drivers/media/rc/rc-keytable.c
@@ -818,6 +818,7 @@ static void rc_input_close(struct input_dev *idev)
 /**
  * rc_keytable_create() - creates a new keytable
  * @dev:   the struct rc_dev device this keytable should belong to
+ * @name:  the userfriendly name of this keymap
  * @map_name:  the name of the keymap to autoload
  * @return:a new struct rc_keytable pointer or NULL on error
  *
@@ -825,7 +826,9 @@ static void rc_input_close(struct input_dev *idev)
  * keytable and an input device along with some state (whether a key
  * is currently pressed or not, etc).
  */
-struct rc_keytable *rc_keytable_create(struct rc_dev *dev, const char 
*map_name)
+struct rc_keytable *rc_keytable_create(struct rc_dev *dev,
+  const char *name,
+  const char *map_name)
 {
struct rc_keytable *kt;
struct input_dev *idev = NULL;
@@ -842,6 +845,7 @@ struct rc_keytable *rc_keytable_create(struct rc_dev *dev, 
const char *map_name)
 
kt-idev = idev;
kt-dev = dev;
+   snprintf(kt-name, sizeof(*kt-name), name ? name : undefined);
idev-getkeycode = ir_getkeycode;
idev-setkeycode = ir_setkeycode;
idev-open = rc_input_open;
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 47e778b..a9c7226 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -496,7 +496,8 @@ void rc_free_device(struct rc_dev *dev)
 }
 EXPORT_SYMBOL_GPL(rc_free_device);
 
-static int rc_add_keytable(struct rc_dev *dev, const char *map_name)
+static int rc_add_keytable(struct rc_dev *dev, const char *name,
+  const char *map_name)
 {
struct rc_keytable *kt;
unsigned i;
@@ -508,7 +509,7 @@ static int rc_add_keytable(struct rc_dev *dev, const char 
*map_name)
if (i = ARRAY_SIZE(dev-keytables))
return -ENFILE;
 
-   kt = rc_keytable_create(dev, map_name);
+   kt = rc_keytable_create(dev, name, map_name);
if (!kt)
return -ENOMEM;
 
@@ -518,19 +519,21 @@ static int rc_add_keytable(struct rc_dev *dev, const char 
*map_name)
return 0;
 }
 
-static void rc_remove_keytable(struct rc_dev *dev, unsigned i)
+static int rc_remove_keytable(struct rc_dev *dev, unsigned i)
 {
struct rc_keytable *kt;
 
-   if (i = ARRAY_SIZE(dev-keytables))
-   return;
-
kt = dev-keytables[i];
rcu_assign_pointer(dev-keytables[i], NULL);
if (kt)
list_del_rcu(kt-node);
synchronize_rcu();
+
+   if (!kt)
+   return -EINVAL;
+
rc_keytable_destroy(kt);
+   return 0;
 }
 
 int rc_register_device(struct rc_dev *dev)
@@ -593,7 +596,7 @@ int rc_register_device(struct rc_dev *dev)
if (rc)
goto out_chardev;
 
-   rc = rc_add_keytable(dev, dev-map_name);
+   rc = rc_add_keytable(dev, dev-map_name, dev-map_name);
if (rc  0)
goto out_device;
 
@@ -938,6 +941,8 @@ static long rc_do_ioctl(struct rc_dev *dev, unsigned int 
cmd, unsigned long arg)
unsigned int __user *ip = (unsigned int __user *)p;
struct rc_ir_rx rx;
struct rc_ir_tx tx;
+   struct rc_keytable_ioctl ktio;
+   struct rc_keytable *kt;
int error;
 
switch (cmd) {
@@ -999,8 +1004,69 @@ static long rc_do_ioctl(struct rc_dev *dev, unsigned int 
cmd, unsigned long arg)
return -EFAULT;
 
return 0;
-   }
 
+   case RCIOCADDTABLE:
+   if (copy_from_user(ktio, p, sizeof(ktio)))

[PATCH 18/43] rc-core: add an ioctl for setting IR RX settings

2012-05-23 Thread David Härdeman
This adds a complementary ioctl to allow IR RX settings to be
changed.

Userspace is expected to first call RCIOCGIRRX, change the relevant parameters
in struct rc_ir_rx and then call RCIOCSIRRX.

The struct will be updated to reflect what the driver actually set the
parameters to (as all values may not be possible and some might have
to be approximated, e.g. because the hardware only supports some fixed
values) so that userspace knows the end result.

The LIRC driver is also changed to use the new RCIOCGIRRX and RCIOCSIRRX
methods as an alternative to the old functionality. This allows several
operations in struct rc_dev to be deprecated.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/ir-lirc-codec.c |   53 +-
 drivers/media/rc/rc-core-priv.h  |3 ++
 drivers/media/rc/rc-main.c   |   53 +-
 include/media/rc-core.h  |   13 ++---
 4 files changed, 92 insertions(+), 30 deletions(-)

diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 795cbdf..767fd06 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -160,6 +160,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int 
cmd,
u32 __user *argp = (u32 __user *)(arg);
int ret = 0;
__u32 val = 0, tmp;
+   struct rc_ir_rx rx;
 
lirc = lirc_get_pdata(filep);
if (!lirc)
@@ -211,15 +212,23 @@ static long ir_lirc_ioctl(struct file *filep, unsigned 
int cmd,
 
/* RX settings */
case LIRC_SET_REC_CARRIER:
-   if (!dev-s_rx_carrier_range)
-   return -ENOSYS;
-
-   if (val = 0)
+   if (val = 0 || val  dev-raw-lirc.carrier_low)
return -EINVAL;
 
-   return dev-s_rx_carrier_range(dev,
-  dev-raw-lirc.carrier_low,
-  val);
+   if (dev-s_rx_carrier_range)
+   return dev-s_rx_carrier_range(dev,
+  
dev-raw-lirc.carrier_low,
+  val);
+
+   if (dev-get_ir_rx  dev-set_ir_rx) {
+   rc_init_ir_rx(dev, rx);
+   dev-get_ir_rx(dev, rx);
+   rx.freq_min = dev-raw-lirc.carrier_low;
+   rx.freq_max = val;
+   return dev-set_ir_rx(dev, rx);
+   }
+
+   return -ENOSYS;
 
case LIRC_SET_REC_CARRIER_RANGE:
if (val = 0)
@@ -233,16 +242,34 @@ static long ir_lirc_ioctl(struct file *filep, unsigned 
int cmd,
break;
 
case LIRC_SET_WIDEBAND_RECEIVER:
-   if (!dev-s_learning_mode)
-   return -ENOSYS;
+   if (dev-s_learning_mode)
+   return dev-s_learning_mode(dev, !!val);
+
+   if (dev-get_ir_rx  dev-set_ir_rx) {
+   rc_init_ir_rx(dev, rx);
+   dev-get_ir_rx(dev, rx);
+   rx.rx_enabled = (!!val) ? rx.rx_learning : 
~rx.rx_learning;
+   rx.rx_enabled = rx.rx_supported;
+   return dev-set_ir_rx(dev, rx);
+   }
 
-   return dev-s_learning_mode(dev, !!val);
+   return -ENOSYS;
 
case LIRC_SET_MEASURE_CARRIER_MODE:
-   if (!dev-s_carrier_report)
-   return -ENOSYS;
+   if (dev-s_carrier_report)
+   return dev-s_carrier_report(dev, !!val);
+
+   if (dev-get_ir_rx  dev-set_ir_rx) {
+   rc_init_ir_rx(dev, rx);
+   dev-get_ir_rx(dev, rx);
+   if (!!val)
+   rx.flags |= RC_IR_RX_MEASURE_CARRIER;
+   else
+   rx.flags = ~RC_IR_RX_MEASURE_CARRIER;
+   return dev-set_ir_rx(dev, rx);
+   }
 
-   return dev-s_carrier_report(dev, !!val);
+   return -ENOSYS;
 
/* Generic timeout support */
case LIRC_GET_MIN_TIMEOUT:
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index 6a40bc9..8db5bbc 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -149,6 +149,9 @@ int ir_raw_handler_register(struct ir_raw_handler 
*ir_raw_handler);
 void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
 void ir_raw_init(void);
 
+/* Only to be used by rc-core and ir-lirc-codec */
+void rc_init_ir_rx(struct rc_dev *dev, struct rc_ir_rx *rx);
+
 /*
  * Decoder initialization code
  *
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 2d3f421..390673c 100644
--- a/drivers/media/rc/rc-main.c
+++ 

[PATCH 15/43] rc-core: add ioctl support to the rc chardev

2012-05-23 Thread David Härdeman
Add basic support for ioctl operations on the rc chardev.

Only two ioctl's are defined for now: one to get the rc-core
version and one to get the driver type of a given chardev.

Userspace is expected to make sure that both match the expected
values before proceeding with any ioctl/read/write ops.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 Documentation/ioctl/ioctl-number.txt |1 +
 drivers/media/rc/rc-main.c   |   66 ++
 include/media/rc-core.h  |   19 ++
 3 files changed, 86 insertions(+)

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index e34b531..2a69c0d 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -269,6 +269,7 @@ Code  Seq#(hex) Include FileComments
 'v'C0-FF   linux/meye.hconflict!
 'v'D0-DF   drivers/media/video/cpia2/cpia2dev.hconflict!
 'w'all CERN SCI driver
+'x'all media/rc-core.h Remote Control drivers
 'y'00-1F   packet based user level communications
mailto:zap...@interlan.net
 'z'00-3F   CAN bus cardconflict!
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 3389822..d9ed1a8 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1663,6 +1663,68 @@ static int rc_fasync(int fd, struct file *file, int on)
return fasync_helper(fd, file, on, client-fasync);
 }
 
+/**
+ * rc_do_ioctl() - internal implementation of ioctl handling
+ * @dev:   the struct rc_dev to perform the command on
+ * @cmd:   the ioctl command to perform
+ * @arg:   the argument to the ioctl cmd
+ * @return:zero on success, or a negative error code
+ *
+ * This function (which is called with the @dev mutex held) performs
+ * the actual processing of ioctl commands.
+ */
+static long rc_do_ioctl(struct rc_dev *dev, unsigned int cmd, unsigned long 
arg)
+{
+   void __user *p = (void __user *)arg;
+   unsigned int __user *ip = (unsigned int __user *)p;
+
+   switch (cmd) {
+
+   case RCIOCGVERSION:
+   return put_user(RC_VERSION, ip);
+
+   case RCIOCGTYPE:
+   return put_user(dev-driver_type, ip);
+   }
+
+   return -EINVAL;
+}
+
+/**
+ * rc_ioctl() - allows userspace to do ioctl operations on the rc device file
+ * @fd:the file descriptor corresponding to the opened rc 
device
+ * @file:  the struct file corresponding to the previous open()
+ * @cmd:   the ioctl command to perform
+ * @arg:   the argument to the ioctl cmd
+ * @return:zero on success, or a negative error code
+ *
+ * This function (which implements the ioctl functionality in
+ * struct file_operations) allows userspace to perform various ioctl
+ * operations on a rc device file.
+ */
+static long rc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+   struct rc_client *client = file-private_data;
+   struct rc_dev *dev = client-dev;
+   int ret;
+
+   ret = mutex_lock_interruptible(dev-lock);
+   if (ret)
+   return ret;
+
+   if (!dev-exist) {
+   ret = -ENODEV;
+   goto out;
+   }
+
+   ret = rc_do_ioctl(dev, cmd, arg);
+
+out:
+   mutex_unlock(dev-lock);
+   return ret;
+}
+
+
 static const struct file_operations rc_fops = {
.owner  = THIS_MODULE,
.open   = rc_open,
@@ -1671,6 +1733,10 @@ static const struct file_operations rc_fops = {
.write  = rc_write,
.poll   = rc_poll,
.fasync = rc_fasync,
+   .unlocked_ioctl = rc_ioctl,
+#ifdef CONFIG_COMPAT
+   .compat_ioctl   = rc_ioctl,
+#endif
 };
 
 static int __init rc_core_init(void)
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index 1810984..e3d445b 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -29,6 +29,25 @@ do { 
\
pr_debug(%s:  fmt, __func__, ##__VA_ARGS__);  \
 } while (0)
 
+#define RC_VERSION 0x01
+
+/*
+ * ioctl definitions
+ *
+ * Note: userspace programs which wish to interact with /dev/rc/rc? devices
+ *  should make sure that the RC version and driver type is known
+ *  (by using RCIOCGVERSION and RCIOCGTYPE) before continuing with any
+ *  read/write/ioctl ops.
+ */
+#define RC_IOC_MAGIC   'x'
+
+/* get rc version */
+#define RCIOCGVERSION  _IOR(RC_IOC_MAGIC, 0x01, unsigned int)
+
+/* get driver/hardware type */
+#define RCIOCGTYPE _IOR(RC_IOC_MAGIC, 0x02, unsigned int)
+
+
 enum rc_driver_type {
RC_DRIVER_SCANCODE = 0, /* Driver or hardware generates a scancode */
RC_DRIVER_IR_RAW,   /* Needs a Infra-Red pulse/space decoder */

--
To unsubscribe from this list: send 

[PATCH 36/43] rc-core: fix various sparse warnings

2012-05-23 Thread David Härdeman
Fix various sparse warnings under drivers/media/rc/*.c, mostly
by making functions static.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/ene_ir.c  |2 +-
 drivers/media/rc/fintek-cir.c  |4 ++--
 drivers/media/rc/imon.c|8 
 drivers/media/rc/ite-cir.c |4 ++--
 drivers/media/rc/nuvoton-cir.c |4 ++--
 5 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c
index eb107e8..2c2cfd5 100644
--- a/drivers/media/rc/ene_ir.c
+++ b/drivers/media/rc/ene_ir.c
@@ -329,7 +329,7 @@ static int ene_rx_get_sample_reg(struct ene_device *dev)
 }
 
 /* Sense current received carrier */
-void ene_rx_sense_carrier(struct ene_device *dev)
+static void ene_rx_sense_carrier(struct ene_device *dev)
 {
DEFINE_IR_RAW_EVENT(ev);
 
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c
index 01e6ef8..ac949ae 100644
--- a/drivers/media/rc/fintek-cir.c
+++ b/drivers/media/rc/fintek-cir.c
@@ -675,12 +675,12 @@ static struct pnp_driver fintek_driver = {
.shutdown   = fintek_shutdown,
 };
 
-int fintek_init(void)
+static int __init fintek_init(void)
 {
return pnp_register_driver(fintek_driver);
 }
 
-void fintek_exit(void)
+static void __exit fintek_exit(void)
 {
pnp_unregister_driver(fintek_driver);
 }
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index d98778b..8573977 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -78,11 +78,11 @@ static int display_open(struct inode *inode, struct file 
*file);
 static int display_close(struct inode *inode, struct file *file);
 
 /* VFD write operation */
-static ssize_t vfd_write(struct file *file, const char *buf,
+static ssize_t vfd_write(struct file *file, const char __user *buf,
 size_t n_bytes, loff_t *pos);
 
 /* LCD file_operations override function prototypes */
-static ssize_t lcd_write(struct file *file, const char *buf,
+static ssize_t lcd_write(struct file *file, const char __user *buf,
 size_t n_bytes, loff_t *pos);
 
 /*** G L O B A L S ***/
@@ -818,7 +818,7 @@ static struct attribute_group imon_rf_attr_group = {
  * than 32 bytes are provided spaces will be appended to
  * generate a full screen.
  */
-static ssize_t vfd_write(struct file *file, const char *buf,
+static ssize_t vfd_write(struct file *file, const char __user *buf,
 size_t n_bytes, loff_t *pos)
 {
int i;
@@ -905,7 +905,7 @@ exit:
  * display whatever diacritics you need, and so on), but it's also
  * a lot more complicated than most LCDs...
  */
-static ssize_t lcd_write(struct file *file, const char *buf,
+static ssize_t lcd_write(struct file *file, const char __user *buf,
 size_t n_bytes, loff_t *pos)
 {
int retval = 0;
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
index 6721767..44759db 100644
--- a/drivers/media/rc/ite-cir.c
+++ b/drivers/media/rc/ite-cir.c
@@ -1705,12 +1705,12 @@ static struct pnp_driver ite_driver = {
.shutdown   = ite_shutdown,
 };
 
-int ite_init(void)
+static int __init ite_init(void)
 {
return pnp_register_driver(ite_driver);
 }
 
-void ite_exit(void)
+static void __exit ite_exit(void)
 {
pnp_unregister_driver(ite_driver);
 }
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index 0548db4..915074e 100644
--- a/drivers/media/rc/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -1223,12 +1223,12 @@ static struct pnp_driver nvt_driver = {
.shutdown   = nvt_shutdown,
 };
 
-int nvt_init(void)
+static int __init nvt_init(void)
 {
return pnp_register_driver(nvt_driver);
 }
 
-void nvt_exit(void)
+static void __exit nvt_exit(void)
 {
pnp_unregister_driver(nvt_driver);
 }

--
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 06/43] rc-core: rename ir_input_class to rc_class

2012-05-23 Thread David Härdeman
The name is already misleading and will be more so in the future as the
connection to the input subsystem is obscured away further.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-main.c |   12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 4adaa87..0e50a84 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -815,14 +815,14 @@ static void ir_close(struct input_dev *idev)
 }
 
 /* class for /sys/class/rc */
-static char *ir_devnode(struct device *dev, umode_t *mode)
+static char *rc_devnode(struct device *dev, umode_t *mode)
 {
return kasprintf(GFP_KERNEL, rc/%s, dev_name(dev));
 }
 
-static struct class ir_input_class = {
+static struct class rc_class = {
.name   = rc,
-   .devnode= ir_devnode,
+   .devnode= rc_devnode,
 };
 
 /*
@@ -1112,7 +1112,7 @@ struct rc_dev *rc_allocate_device(void)
setup_timer(dev-timer_keyup, ir_timer_keyup, (unsigned long)dev);
 
dev-dev.type = rc_dev_type;
-   dev-dev.class = ir_input_class;
+   dev-dev.class = rc_class;
device_initialize(dev-dev);
 
__module_get(THIS_MODULE);
@@ -1285,7 +1285,7 @@ EXPORT_SYMBOL_GPL(rc_unregister_device);
 
 static int __init rc_core_init(void)
 {
-   int rc = class_register(ir_input_class);
+   int rc = class_register(rc_class);
if (rc) {
printk(KERN_ERR rc_core: unable to register rc class\n);
return rc;
@@ -1298,7 +1298,7 @@ static int __init rc_core_init(void)
 
 static void __exit rc_core_exit(void)
 {
-   class_unregister(ir_input_class);
+   class_unregister(rc_class);
rc_map_unregister(empty_map);
 }
 

--
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 38/43] rc-ir-raw: add various rc_events

2012-05-23 Thread David Härdeman
Reporting pulse/space events via the /dev/rc/rcX device node is an
important step towards having feature parity with LIRC.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-ir-raw.c |   11 +++
 include/media/rc-core.h  |   10 ++
 2 files changed, 21 insertions(+)

diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index 88a2932..e6a6eea 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -73,6 +73,17 @@ int ir_raw_event_store(struct rc_dev *dev, struct 
ir_raw_event *ev)
IR_dprintk(2, sample: (%05dus %s)\n,
   TO_US(ev-duration), TO_STR(ev-pulse));
 
+   if (ev-reset)
+   rc_event(dev, RC_IR_RAW, RC_IR_RAW_RESET, 1);
+   else if (ev-carrier_report)
+   rc_event(dev, RC_IR_RAW, RC_IR_RAW_CARRIER, ev-carrier);
+   else if (ev-timeout)
+   rc_event(dev, RC_IR_RAW, RC_IR_RAW_STOP, 1);
+   else if (ev-pulse)
+   rc_event(dev, RC_IR_RAW, RC_IR_RAW_PULSE, ev-duration);
+   else
+   rc_event(dev, RC_IR_RAW, RC_IR_RAW_SPACE, ev-duration);
+
if (kfifo_in(dev-raw-kfifo, ev, 1) != 1)
return -ENOMEM;
 
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index ab9a72e..f2ff7f7 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -378,6 +378,7 @@ struct rc_keytable {
 #define RC_DEBUG   0x0
 #define RC_CORE0x1
 #define RC_KEY 0x2
+#define RC_IR_RAW  0x3
 
 /* RC_CORE codes */
 #define RC_CORE_DROPPED0x0
@@ -388,6 +389,15 @@ struct rc_keytable {
 #define RC_KEY_SCANCODE0x2
 #define RC_KEY_TOGGLE  0x3
 
+/* RC_IR_RAW codes */
+#define RC_IR_RAW_SPACE0x0
+#define RC_IR_RAW_PULSE0x1
+#define RC_IR_RAW_START0x2
+#define RC_IR_RAW_STOP 0x3
+#define RC_IR_RAW_RESET0x4
+#define RC_IR_RAW_CARRIER  0x5
+#define RC_IR_RAW_DUTY_CYCLE   0x6
+
 /**
  * struct rc_event - used to communicate rc events to userspace
  * @type:  the event type

--
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 34/43] rc-core: rename mutex

2012-05-23 Thread David Härdeman
Having a mutex named lock is a bit misleading.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-keytable.c |8 
 drivers/media/rc/rc-main.c |   22 +++---
 include/media/rc-core.h|4 ++--
 3 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/media/rc/rc-keytable.c b/drivers/media/rc/rc-keytable.c
index d5b1d88..84c6e96 100644
--- a/drivers/media/rc/rc-keytable.c
+++ b/drivers/media/rc/rc-keytable.c
@@ -699,14 +699,14 @@ static int rc_input_open(struct input_dev *idev)
struct rc_keytable *kt = input_get_drvdata(idev);
struct rc_dev *dev = kt-dev;
 
-   error = mutex_lock_interruptible(dev-lock);
+   error = mutex_lock_interruptible(dev-mutex);
if (error)
return error;
 
if (dev-users++ == 0  dev-open)
error = dev-open(dev);
 
-   mutex_unlock(dev-lock);
+   mutex_unlock(dev-mutex);
return error;
 }
 
@@ -722,12 +722,12 @@ static void rc_input_close(struct input_dev *idev)
struct rc_keytable *kt = input_get_drvdata(idev);
struct rc_dev *dev = kt-dev;
 
-   mutex_lock(dev-lock);
+   mutex_lock(dev-mutex);
 
if (--dev-users == 0  dev-close)
dev-close(dev);
 
-   mutex_unlock(dev-lock);
+   mutex_unlock(dev-mutex);
 }
 
 /**
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index c2c42f9..14728fc 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -231,7 +231,7 @@ static struct {
  * It returns the protocol names of supported protocols.
  * Enabled protocols are printed in brackets.
  *
- * dev-lock is taken to guard against races between store_protocols
+ * dev-mutex is taken to guard against races between store_protocols
  * and show_protocols.
  */
 static ssize_t show_protocols(struct device *device,
@@ -246,7 +246,7 @@ static ssize_t show_protocols(struct device *device,
if (!dev)
return -EINVAL;
 
-   mutex_lock(dev-lock);
+   mutex_lock(dev-mutex);
 
enabled = dev-enabled_protocols;
allowed = dev-get_protocols(dev);
@@ -269,7 +269,7 @@ static ssize_t show_protocols(struct device *device,
tmp--;
*tmp = '\n';
 
-   mutex_unlock(dev-lock);
+   mutex_unlock(dev-mutex);
 
return tmp + 1 - buf;
 }
@@ -290,7 +290,7 @@ static ssize_t show_protocols(struct device *device,
  * Returns -EINVAL if an invalid protocol combination or unknown protocol name
  * is used, otherwise @len.
  *
- * dev-lock is taken to guard against races between store_protocols and
+ * dev-mutex is taken to guard against races between store_protocols and
  * show_protocols.
  */
 static ssize_t store_protocols(struct device *device,
@@ -310,7 +310,7 @@ static ssize_t store_protocols(struct device *device,
if (!dev)
return -EINVAL;
 
-   mutex_lock(dev-lock);
+   mutex_lock(dev-mutex);
 
if (dev-driver_type != RC_DRIVER_SCANCODE  !dev-raw) {
IR_dprintk(1, Protocol switching not supported\n);
@@ -383,7 +383,7 @@ static ssize_t store_protocols(struct device *device,
ret = len;
 
 out:
-   mutex_unlock(dev-lock);
+   mutex_unlock(dev-mutex);
return ret;
 }
 
@@ -467,7 +467,7 @@ struct rc_dev *rc_allocate_device(void)
init_waitqueue_head(dev-rxwait);
init_waitqueue_head(dev-txwait);
spin_lock_init(dev-txlock);
-   mutex_init(dev-lock);
+   mutex_init(dev-mutex);
 
dev-dev.type = rc_dev_type;
dev-dev.class = rc_class;
@@ -623,11 +623,11 @@ void rc_unregister_device(struct rc_dev *dev)
if (!dev)
return;
 
-   mutex_lock(dev-lock);
+   mutex_lock(dev-mutex);
dev-exist = false;
for (i = 0; i  ARRAY_SIZE(dev-keytables); i++)
rc_remove_keytable(dev, i);
-   mutex_unlock(dev-lock);
+   mutex_unlock(dev-mutex);
 
mutex_lock(rc_dev_table_mutex);
rc_dev_table[dev-minor] = NULL;
@@ -1071,7 +1071,7 @@ static long rc_ioctl(struct file *file, unsigned int cmd, 
unsigned long arg)
struct rc_dev *dev = client-dev;
int ret;
 
-   ret = mutex_lock_interruptible(dev-lock);
+   ret = mutex_lock_interruptible(dev-mutex);
if (ret)
return ret;
 
@@ -1083,7 +1083,7 @@ static long rc_ioctl(struct file *file, unsigned int cmd, 
unsigned long arg)
ret = rc_do_ioctl(dev, cmd, arg);
 
 out:
-   mutex_unlock(dev-lock);
+   mutex_unlock(dev-mutex);
return ret;
 }
 
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index cf66e91..ab9a72e 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -226,7 +226,7 @@ struct ir_raw_event {
  * @driver_name: name of the hardware driver which registered this device
  * @map_name: name of the default keymap
  * @rc_map: current scan/key table
- * @lock: used where a more 

[PATCH 42/43] rc-core: move remaining keytable functions

2012-05-23 Thread David Härdeman
Move some more keytable related functionality over to rc-keytable.c which
allows more implementational details to be obscured away.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-core-priv.h |   11 +-
 drivers/media/rc/rc-keytable.c  |  213 +--
 drivers/media/rc/rc-main.c  |  132 +---
 include/media/rc-core.h |   44 
 4 files changed, 193 insertions(+), 207 deletions(-)

diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index 376030e..3f056e3 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -156,13 +156,10 @@ void ir_raw_init(void);
 /*
  * Methods from rc-keytable.c to be used internally
  */
-void rc_keytable_keyup(struct rc_keytable *kt);
-void rc_keytable_repeat(struct rc_keytable *kt);
-void rc_keytable_keydown(struct rc_keytable *kt, enum rc_type protocol,
-u64 scancode, u8 toggle, bool autokeyup);
-struct rc_keytable *rc_keytable_create(struct rc_dev *dev, const char *name,
-  const char *map_name);
-void rc_keytable_destroy(struct rc_keytable *kt);
+int rc_keytable_add(struct rc_dev *dev, const char *name, const char 
*map_name);
+int rc_keytable_remove(struct rc_dev *dev, unsigned i);
+int rc_keytable_get_name(struct rc_dev *dev, unsigned i,
+char *buf, size_t bufsize);
 
 /* Only to be used by rc-core and ir-lirc-codec */
 void rc_init_ir_rx(struct rc_dev *dev, struct rc_ir_rx *rx);
diff --git a/drivers/media/rc/rc-keytable.c b/drivers/media/rc/rc-keytable.c
index d0777cb..027a703 100644
--- a/drivers/media/rc/rc-keytable.c
+++ b/drivers/media/rc/rc-keytable.c
@@ -29,6 +29,50 @@
 /* FIXME: RC_KEYPRESS_TIMEOUT should be protocol specific */
 #define RC_KEYPRESS_TIMEOUT 250
 
+/**
+ * struct rc_scan - rcu-friendly scancode-keycode table
+ * @len:number of elements in the table array
+ * @table:  array of struct rc_map_table elements
+ */
+struct rc_scan {
+   unsigned len;
+   struct rc_map_table table[];
+};
+
+/**
+ * struct rc_keytable - represents one keytable for a rc_dev device
+ * @node:   used to iterate over all keytables for a rc_dev device
+ * @dev:the rc_dev device this keytable belongs to
+ * @idev:   the input_dev device which belongs to this keytable
+ * @name:   the user-friendly name of this keytable
+ * @scan_mutex: protects @scan against concurrent writers
+ * @scan:   the current scancode-keycode table
+ * @key_lock:   protects the key state
+ * @key_pressed:whether a key is currently pressed or not
+ * @last_keycode:   keycode of the last keypress
+ * @last_protocol:  protocol of the last keypress
+ * @last_scancode:  scancode of the last keypress
+ * @last_toggle:toggle of the last keypress
+ * @timer_keyup:responsible for the auto-release of keys
+ * @keyup_jiffies:  when the key should be auto-released
+ */
+struct rc_keytable {
+   struct list_headnode;
+   struct rc_dev   *dev;
+   struct input_dev*idev;
+   charname[RC_KEYTABLE_NAME_SIZE];
+   struct mutexscan_mutex;
+   struct rc_scan __rcu*scan;
+   spinlock_t  key_lock;
+   boolkey_pressed;
+   u32 last_keycode;
+   enum rc_typelast_protocol;
+   u64 last_scancode;
+   u8  last_toggle;
+   struct timer_list   timer_keyup;
+   unsigned long   keyup_jiffies;
+};
+
 /* Used to keep track of known keymaps */
 static LIST_HEAD(rc_map_list);
 static DEFINE_SPINLOCK(rc_map_lock);
@@ -557,19 +601,26 @@ static void rc_do_keyup(struct rc_keytable *kt, bool sync)
 
 /**
  * rc_keyup() - signals the release of a keypress
- * @kt:the struct rc_keytable descriptor of the keytable
+ * @dev:the struct rc_dev descriptor of the device
  *
  * This routine is used to signal that a key has been released on the
  * remote control.
  */
-void rc_keytable_keyup(struct rc_keytable *kt)
+void rc_keyup(struct rc_dev *dev)
 {
+   struct rc_keytable *kt;
unsigned long flags;
 
-   spin_lock_irqsave(kt-key_lock, flags);
-   rc_do_keyup(kt, true);
-   spin_unlock_irqrestore(kt-key_lock, flags);
+   rcu_read_lock();
+   list_for_each_entry_rcu(kt, dev-keytable_list, node) {
+   spin_lock_irqsave(kt-key_lock, flags);
+   rc_do_keyup(kt, true);
+   spin_unlock_irqrestore(kt-key_lock, flags);
+   }
+   rcu_read_unlock();
 }
+EXPORT_SYMBOL_GPL(rc_keyup);
+
 
 /**
  * rc_timer_keyup() - generates a keyup event after a timeout
@@ 

[PATCH 16/43] rc-core: add an ioctl for getting IR RX settings

2012-05-23 Thread David Härdeman
LIRC currently supports quite a number of ioctl's for getting/setting
various TX and RX parameters. One problem with the one-ioctl-per-parameter
approach is that it might be quite elaborate to reprogram the hardware
(an operation which will have to be done once for every parameter change).

LIRC has approached this problem by providing something similar to
database transactions (ioctl commands LIRC_SETUP_START and LIRC_SETUP_END)
which is one (complicated) way of doing it.

The proposed approach for rc-core instead uses a struct with all known
parameters defined in one go. Drivers are expected to fill in the struct
with all the parameters that apply to them while leaving the rest intact.

I've looked at parameters defined in: LIRC, current rc-core, and in Microsoft
CIRClass drivers. The current struct rc_ir_rx should be a superset of all
three and also has room for further additions. Hopefully this should be fairly
complete and future-proof, please check carefully that you favourite
parameter is supported to satisfy your OCD.

Also, it would be interesting to know if carrier reporting is actually an
expensive operation (which should be explicitly enabled by setting the
appropriate flag as now) or not (in which case it should always be on).

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-main.c |   28 +++
 include/media/rc-core.h|   65 
 2 files changed, 93 insertions(+)

diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index d9ed1a8..2d3f421 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1677,6 +1677,7 @@ static long rc_do_ioctl(struct rc_dev *dev, unsigned int 
cmd, unsigned long arg)
 {
void __user *p = (void __user *)arg;
unsigned int __user *ip = (unsigned int __user *)p;
+   struct rc_ir_rx rx;
 
switch (cmd) {
 
@@ -1685,6 +1686,33 @@ static long rc_do_ioctl(struct rc_dev *dev, unsigned int 
cmd, unsigned long arg)
 
case RCIOCGTYPE:
return put_user(dev-driver_type, ip);
+
+   case RCIOCGIRPSIZE:
+   return put_user(ARRAY_SIZE(rx.protocols_supported), ip);
+
+   case RCIOCGIRRX:
+   memset(rx, 0, sizeof(rx));
+   rx.rx_supported = 0x1;
+   rx.rx_enabled = 0x1;
+   rx.rx_connected = 0x1;
+   rx.protocols_enabled[0] = dev-enabled_protocols;
+   if (dev-driver_type == RC_DRIVER_SCANCODE)
+   rx.protocols_supported[0] = dev-allowed_protos;
+   else
+   rx.protocols_supported[0] = 
ir_raw_get_allowed_protocols();
+   rx.timeout = dev-timeout;
+   rx.timeout_min = dev-min_timeout;
+   rx.timeout_max = dev-max_timeout;
+   rx.resolution = dev-rx_resolution;
+
+   /* See if the driver wishes to override anything */
+   if (dev-get_ir_rx)
+   dev-get_ir_rx(dev, rx);
+
+   if (copy_to_user(p, rx, sizeof(rx)))
+   return -EFAULT;
+
+   return 0;
}
 
return -EINVAL;
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index e3d445b..5669b64 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -47,6 +47,69 @@ do { 
\
 /* get driver/hardware type */
 #define RCIOCGTYPE _IOR(RC_IOC_MAGIC, 0x02, unsigned int)
 
+/* get size of protocols array (i.e. multiples of u64) for struct rc_ir_rx */
+#define RCIOCGIRPSIZE  _IOR(RC_IOC_MAGIC, 0x03, unsigned int)
+
+/* get ir rx parameters */
+#define RCIOCGIRRX _IOC(_IOC_READ, RC_IOC_MAGIC, 0x04, sizeof(struct 
rc_ir_rx))
+
+/**
+ * struct rc_ir_rx - used to get all IR RX parameters in one go
+ * @flags: device specific flags (only %RC_IR_RX_MEASURE_CARRIER is
+ * currently defined)
+ * @rx_supported: bitmask of supported (i.e. possible) receivers
+ * @rx_enabled: bitmask of enabled receivers
+ * @rx_connected: bitmask of connected receivers
+ * @rx_learning: bitmask of learning receivers
+ * @protocols_supported: bitmask of supported protocols
+ * @protocols_enabled: bitmask of enabled protocols
+ * @freq_min: min carrier frequency
+ * @freq_max: max carrier frequency
+ * @duty_min: min duty cycle
+ * @duty_max: max duty cycle
+ * @timeout: current timeout (i.e. silence-before-idle)
+ * @timeout_min: min timeout
+ * @timeout_max: max timeout
+ * @filter_space: shorter spaces may be filtered
+ * @filter_space_min: min space filter value
+ * @filter_space_max: max space filter value
+ * @filter_pulse: shorter pulses may be filtered
+ * @filter_pulse_min: min pulse filter value
+ * @filter_pulse_max: max pulse filter value
+ * @resolution: current pulse/space resolution
+ * @resolution_min: min resolution
+ * @resolution_max: max resolution
+ * @reserved: for future use, set to zero
+ */
+struct rc_ir_rx {

[PATCH 33/43] rc-ir-raw: simplify locking

2012-05-23 Thread David Härdeman
Simplify and improve the locking in rc-ir-raw by making better use of
the existing kfifo functionality and by using RCU where possible.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-core-priv.h |6 +-
 drivers/media/rc/rc-ir-raw.c|  119 ---
 2 files changed, 52 insertions(+), 73 deletions(-)

diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index b2a5d99..b0e1686 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -33,11 +33,13 @@ struct ir_raw_handler {
int (*raw_unregister)(struct rc_dev *dev);
 };
 
+/* max number of pulse/space transitions to buffer */
+#define RC_MAX_IR_EVENTS   512
+
 struct ir_raw_event_ctrl {
struct list_headlist;   /* to keep track of raw 
clients */
struct task_struct  *thread;
-   spinlock_t  lock;
-   struct kfifo_rec_ptr_1  kfifo;  /* fifo for the 
pulse/space durations */
+   DECLARE_KFIFO(kfifo, struct ir_raw_event, RC_MAX_IR_EVENTS); /* for 
pulse/space durations */
ktime_t last_event; /* when last event 
occurred */
enum raw_event_type last_type;  /* last event type */
struct rc_dev   *dev;   /* pointer to the 
parent rc_dev */
diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index a0d3508..42769b4 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -23,15 +23,12 @@
 
 #include rc-core-priv.h
 
-/* Define the max number of pulse/space transitions to buffer */
-#define MAX_IR_EVENT_SIZE  512
-
-/* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */
+/* IR raw clients/handlers, writers synchronize with ir_raw_mutex */
+static DEFINE_MUTEX(ir_raw_mutex);
 static LIST_HEAD(ir_raw_client_list);
-
-/* Used to handle IR raw handler extensions */
-static DEFINE_MUTEX(ir_raw_handler_lock);
 static LIST_HEAD(ir_raw_handler_list);
+
+/* protocols supported by the currently loaded decoders */
 static u64 available_protocols;
 
 static int ir_raw_event_thread(void *data)
@@ -39,32 +36,19 @@ static int ir_raw_event_thread(void *data)
struct ir_raw_event ev;
struct ir_raw_handler *handler;
struct ir_raw_event_ctrl *raw = (struct ir_raw_event_ctrl *)data;
-   int retval;
 
while (!kthread_should_stop()) {
-
-   spin_lock_irq(raw-lock);
-   retval = kfifo_len(raw-kfifo);
-
-   if (retval  sizeof(ev)) {
+   if (kfifo_out(raw-kfifo, ev, 1) == 0) {
set_current_state(TASK_INTERRUPTIBLE);
-
-   if (kthread_should_stop())
-   set_current_state(TASK_RUNNING);
-
-   spin_unlock_irq(raw-lock);
schedule();
continue;
}
 
-   retval = kfifo_out(raw-kfifo, ev, sizeof(ev));
-   spin_unlock_irq(raw-lock);
-
-   mutex_lock(ir_raw_handler_lock);
-   list_for_each_entry(handler, ir_raw_handler_list, list)
+   rcu_read_lock();
+   list_for_each_entry_rcu(handler, ir_raw_handler_list, list)
handler-decode(raw-dev, ev);
+   rcu_read_unlock();
raw-prev_ev = ev;
-   mutex_unlock(ir_raw_handler_lock);
}
 
return 0;
@@ -78,7 +62,8 @@ static int ir_raw_event_thread(void *data)
  * This routine (which may be called from an interrupt context) stores a
  * pulse/space duration for the raw ir decoding state machines. Pulses are
  * signalled as positive values and spaces as negative values. A zero value
- * will reset the decoding state machines.
+ * will reset the decoding state machines. Drivers are responsible for
+ * synchronizing calls to this function.
  */
 int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev)
 {
@@ -88,7 +73,7 @@ int ir_raw_event_store(struct rc_dev *dev, struct 
ir_raw_event *ev)
IR_dprintk(2, sample: (%05dus %s)\n,
   TO_US(ev-duration), TO_STR(ev-pulse));
 
-   if (kfifo_in(dev-raw-kfifo, ev, sizeof(*ev)) != sizeof(*ev))
+   if (kfifo_in(dev-raw-kfifo, ev, 1) != 1)
return -ENOMEM;
 
return 0;
@@ -217,14 +202,8 @@ EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
  */
 void ir_raw_event_handle(struct rc_dev *dev)
 {
-   unsigned long flags;
-
-   if (!dev-raw)
-   return;
-
-   spin_lock_irqsave(dev-raw-lock, flags);
-   wake_up_process(dev-raw-thread);
-   spin_unlock_irqrestore(dev-raw-lock, flags);
+   if (dev-raw)
+   wake_up_process(dev-raw-thread);
 }
 EXPORT_SYMBOL_GPL(ir_raw_event_handle);
 
@@ -233,9 +212,9 @@ static u64
 ir_raw_get_allowed_protocols(struct rc_dev *dev)
 {

[PATCH 32/43] rc-core: split IR raw handling to a separate module

2012-05-23 Thread David Härdeman
Move drivers/media/rc/ir-raw.c to drivers/media/rc/rc-ir-raw.c and make it
a separate kernel module (rc-ir-raw.ko to make it clearer that it belongs to
the rc-* family).

Drivers which use IR decoding must use these functions:
rc_register_ir_raw_device()
rc_unregister_ir_raw_device()
instead of:
rc_register_device()
rc_unregister_device()

This allows scancode drivers to skip lots of unnecessary functionality.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/dvb/dvb-usb/Kconfig   |2 
 drivers/media/dvb/dvb-usb/dvb-usb-remote.c  |7 
 drivers/media/dvb/dvb-usb/dvb-usb.h |2 
 drivers/media/dvb/siano/Kconfig |2 
 drivers/media/dvb/siano/smsir.c |4 
 drivers/media/dvb/siano/smsir.h |2 
 drivers/media/rc/Kconfig|   54 +++-
 drivers/media/rc/Makefile   |3 
 drivers/media/rc/ene_ir.c   |6 
 drivers/media/rc/fintek-cir.c   |6 
 drivers/media/rc/gpio-ir-recv.c |8 -
 drivers/media/rc/ir-raw.c   |  372 ---
 drivers/media/rc/ite-cir.c  |6 
 drivers/media/rc/mceusb.c   |6 
 drivers/media/rc/nuvoton-cir.c  |6 
 drivers/media/rc/rc-core-priv.h |3 
 drivers/media/rc/rc-ir-raw.c|  379 +++
 drivers/media/rc/rc-loopback.c  |6 
 drivers/media/rc/rc-main.c  |   39 +--
 drivers/media/rc/redrat3.c  |6 
 drivers/media/rc/streamzap.c|6 
 drivers/media/rc/winbond-cir.c  |6 
 drivers/media/video/cx23885/Kconfig |2 
 drivers/media/video/cx23885/cx23885-input.c |6 
 drivers/media/video/cx23885/cx23888-ir.c|2 
 drivers/media/video/cx25840/cx25840-ir.c|2 
 drivers/media/video/cx88/Kconfig|2 
 drivers/media/video/cx88/cx88-input.c   |6 
 drivers/media/video/saa7134/Kconfig |2 
 drivers/media/video/saa7134/saa7134-input.c |4 
 drivers/media/video/saa7134/saa7134.h   |2 
 include/media/rc-core.h |   49 ---
 include/media/rc-ir-raw.h   |   68 +
 33 files changed, 557 insertions(+), 519 deletions(-)
 delete mode 100644 drivers/media/rc/ir-raw.c
 create mode 100644 drivers/media/rc/rc-ir-raw.c
 create mode 100644 include/media/rc-ir-raw.h

diff --git a/drivers/media/dvb/dvb-usb/Kconfig 
b/drivers/media/dvb/dvb-usb/Kconfig
index a269493..e9c94f2 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -1,6 +1,6 @@
 config DVB_USB
tristate Support for various USB DVB devices
-   depends on DVB_CORE  USB  I2C  RC_CORE
+   depends on DVB_CORE  USB  I2C  RC_CORE  RC_IR_RAW
help
  By enabling this you will be able to choose the various supported
  USB1.1 and USB2.0 DVB devices.
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c 
b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index 909e95c..6f138c3 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -280,7 +280,10 @@ static int rc_core_dvb_usb_remote_init(struct 
dvb_usb_device *d)
dev-dev.parent = d-udev-dev;
dev-priv = d;
 
-   err = rc_register_device(dev);
+   if (dev-driver_type == RC_DRIVER_IR_RAW)
+   err = rc_register_ir_raw_device(dev);
+   else
+   err = rc_register_device(dev);
if (err  0) {
rc_free_device(dev);
return err;
@@ -341,6 +344,8 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d)
cancel_delayed_work_sync(d-rc_query_work);
if (d-props.rc.mode == DVB_RC_LEGACY)
input_unregister_device(d-input_dev);
+   else if (d-rc_dev-driver_type == RC_DRIVER_IR_RAW)
+   rc_unregister_ir_raw_device(d-rc_dev);
else
rc_unregister_device(d-rc_dev);
}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h 
b/drivers/media/dvb/dvb-usb/dvb-usb.h
index ed886ae..1ce0bb8 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -14,7 +14,7 @@
 #include linux/usb.h
 #include linux/firmware.h
 #include linux/mutex.h
-#include media/rc-core.h
+#include media/rc-ir-raw.h
 
 #include dvb_frontend.h
 #include dvb_demux.h
diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig
index bc6456e..fa2923f 100644
--- a/drivers/media/dvb/siano/Kconfig
+++ b/drivers/media/dvb/siano/Kconfig
@@ -4,7 +4,7 @@
 
 config SMS_SIANO_MDTV
tristate Siano SMS1xxx based MDTV receiver
-   depends on DVB_CORE  RC_CORE  HAS_DMA
+   depends on DVB_CORE  RC_CORE  RC_IR_RAW  HAS_DMA
---help---
  Choose Y or M here if you have MDTV 

[PATCH 17/43] rc-loopback: add RCIOCGIRRX ioctl support

2012-05-23 Thread David Härdeman
As an example, this patch adds support for the new RCIOCGIRRX ioctl
to rc-loopback.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-loopback.c |   22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
index b6a2e58..7977b75 100644
--- a/drivers/media/rc/rc-loopback.c
+++ b/drivers/media/rc/rc-loopback.c
@@ -173,6 +173,27 @@ static int loop_set_carrier_report(struct rc_dev *dev, int 
enable)
return 0;
 }
 
+/**
+ * loop_get_ir_rx() - returns the current RX settings
+ * @dev: the struct rc_dev to get the settings for
+ * @rx: the struct rc_ir_rx to fill in with the current settings
+ *
+ * This function is used to return the current RX settings.
+ */
+static void loop_get_ir_rx(struct rc_dev *dev, struct rc_ir_rx *rx)
+{
+   struct loopback_dev *lodev = dev-priv;
+
+   rx-rx_supported = RXMASK_REGULAR | RXMASK_LEARNING;
+   rx-rx_connected = RXMASK_REGULAR | RXMASK_LEARNING;
+   rx-rx_enabled = lodev-learning ? RXMASK_LEARNING : RXMASK_REGULAR;
+   rx-rx_learning = RXMASK_LEARNING;
+   rx-freq_min = lodev-rxcarriermin;
+   rx-freq_max = lodev-rxcarriermax;
+   rx-duty_min = 1;
+   rx-duty_max = 99;
+}
+
 static int __init loop_init(void)
 {
struct rc_dev *rc;
@@ -206,6 +227,7 @@ static int __init loop_init(void)
rc-s_idle  = loop_set_idle;
rc-s_learning_mode = loop_set_learning_mode;
rc-s_carrier_report= loop_set_carrier_report;
+   rc-get_ir_rx   = loop_get_ir_rx;
 
loopdev.txmask  = RXMASK_REGULAR;
loopdev.txcarrier   = 36000;

--
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 41/43] rc-core: add keytable events

2012-05-23 Thread David Härdeman
Add separe rc device events on keytable addition/removal.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-main.c |2 ++
 include/media/rc-core.h|2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 6c8bc3a..b16dbf4 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -513,6 +513,7 @@ static int rc_add_keytable(struct rc_dev *dev, const char 
*name,
rcu_assign_pointer(dev-keytables[i], kt);
list_add_rcu(kt-node, dev-keytable_list);
synchronize_rcu();
+   rc_event(dev, RC_CORE, RC_CORE_KT_ADDED, i);
return 0;
 }
 
@@ -530,6 +531,7 @@ static int rc_remove_keytable(struct rc_dev *dev, unsigned 
i)
return -EINVAL;
 
rc_keytable_destroy(kt);
+   rc_event(dev, RC_CORE, RC_CORE_KT_REMOVED, i);
return 0;
 }
 
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index ea3dcf4..056275a 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -221,6 +221,8 @@ struct rc_event {
 
 /* RC_CORE codes */
 #define RC_CORE_DROPPED0x0
+#define RC_CORE_KT_ADDED   0x1
+#define RC_CORE_KT_REMOVED 0x2
 
 /* RC_KEY codes */
 #define RC_KEY_REPEAT  0x0

--
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 24/43] rc-core: leave the internals of rc_dev alone

2012-05-23 Thread David Härdeman
Several drivers poke around in the internals of rc_dev, try to
fix them up in preparation for the next round of patches.

drivers/media/rc/ati_remote.c:
Removing the REP_DELAY setting on the input device should not
change how to driver works (as it does a keydown/keyup and has
no real repeat handling).

drivers/media/rc/ir-nec-decoder.c
Obvious fix, leave repeat handling to rc-core

drivers/media/rc/ir-raw.c
Replaced the REP_DELAY value with a static value, which makes more
sense anyway. Why should the time before automatic repeat handling
kicks in define the drivers idea of a long time?

drivers/media/rc/ir-sanyo-decoder.c
Obvious fix, leave repeat handling to rc-core

drivers/media/video/cx231xx/cx231xx-input.c
Just some debug statements to change

drivers/media/video/tm6000/tm6000-input.c
Not sure what the driver is trying to do, however, IR
handling seems incomplete ATM so deleting the offending
parts shouldn't affect funcationality

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/ati_remote.c   |3 ---
 drivers/media/rc/ir-nec-decoder.c   |   10 +++---
 drivers/media/rc/ir-raw.c   |4 +---
 drivers/media/rc/ir-sanyo-decoder.c |   10 +++---
 drivers/media/video/cx231xx/cx231xx-input.c |7 +++
 drivers/media/video/tm6000/tm6000-input.c   |4 
 6 files changed, 10 insertions(+), 28 deletions(-)

diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c
index 229f742..f10af75 100644
--- a/drivers/media/rc/ati_remote.c
+++ b/drivers/media/rc/ati_remote.c
@@ -918,9 +918,6 @@ static int ati_remote_probe(struct usb_interface 
*interface, const struct usb_de
if (err)
goto fail3;
 
-   /* use our delay for rc_dev */
-   ati_remote-rdev-input_dev-rep[REP_DELAY] = repeat_delay;
-
/* Set up and register mouse input device */
if (mouse) {
input_dev = input_allocate_device();
diff --git a/drivers/media/rc/ir-nec-decoder.c 
b/drivers/media/rc/ir-nec-decoder.c
index 1033f30..c92b229 100644
--- a/drivers/media/rc/ir-nec-decoder.c
+++ b/drivers/media/rc/ir-nec-decoder.c
@@ -89,13 +89,9 @@ static int ir_nec_decode(struct rc_dev *dev, struct 
ir_raw_event ev)
data-state = STATE_BIT_PULSE;
return 0;
} else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 
2)) {
-   if (!dev-keypressed) {
-   IR_dprintk(1, Discarding last key repeat: 
event after key up\n);
-   } else {
-   rc_repeat(dev);
-   IR_dprintk(1, Repeat last key\n);
-   data-state = STATE_TRAILER_PULSE;
-   }
+   rc_repeat(dev);
+   IR_dprintk(1, Repeat last key\n);
+   data-state = STATE_TRAILER_PULSE;
return 0;
}
 
diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c
index 7729abe..6ef1510 100644
--- a/drivers/media/rc/ir-raw.c
+++ b/drivers/media/rc/ir-raw.c
@@ -114,20 +114,18 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum 
raw_event_type type)
s64 delta; /* ns */
DEFINE_IR_RAW_EVENT(ev);
int rc = 0;
-   int delay;
 
if (!dev-raw)
return -EINVAL;
 
now = ktime_get();
delta = ktime_to_ns(ktime_sub(now, dev-raw-last_event));
-   delay = MS_TO_NS(dev-input_dev-rep[REP_DELAY]);
 
/* Check for a long duration since last event or if we're
 * being called for the first time, note that delta can't
 * possibly be negative.
 */
-   if (delta  delay || !dev-raw-last_type)
+   if (delta  MS_TO_NS(500) || !dev-raw-last_type)
type |= IR_START_EVENT;
else
ev.duration = delta;
diff --git a/drivers/media/rc/ir-sanyo-decoder.c 
b/drivers/media/rc/ir-sanyo-decoder.c
index a95c869..17ee339 100644
--- a/drivers/media/rc/ir-sanyo-decoder.c
+++ b/drivers/media/rc/ir-sanyo-decoder.c
@@ -112,13 +112,9 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct 
ir_raw_event ev)
break;
 
if (!data-count  geq_margin(ev.duration, SANYO_REPEAT_SPACE, 
SANYO_UNIT / 2)) {
-   if (!dev-keypressed) {
-   IR_dprintk(1, SANYO discarding last key 
repeat: event after key up\n);
-   } else {
-   rc_repeat(dev);
-   IR_dprintk(1, SANYO repeat last key\n);
-   data-state = STATE_INACTIVE;
-   }
+   rc_repeat(dev);
+   

[PATCH 22/43] rc-core: add an ioctl for setting IR TX settings

2012-05-23 Thread David Härdeman
This adds a complementary ioctl to allow IR TX settings to be
changed.

Much like the RCIOCSIRRX functionality, userspace is expected to call
RCIOCGIRTX, change values and then call RCIOCSIRTX and finally inspect
the struct rc_ir_tx to see the results.

Also, LIRC is changed to use the new functionality as an alternative to the
old one and another bunch of operations in struct rc_dev are now deprecated.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/ir-lirc-codec.c |   42 +-
 drivers/media/rc/rc-main.c   |   13 
 include/media/rc-core.h  |   13 
 3 files changed, 54 insertions(+), 14 deletions(-)

diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 767fd06..6811db9 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -161,6 +161,7 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int 
cmd,
int ret = 0;
__u32 val = 0, tmp;
struct rc_ir_rx rx;
+   struct rc_ir_tx tx;
 
lirc = lirc_get_pdata(filep);
if (!lirc)
@@ -190,25 +191,46 @@ static long ir_lirc_ioctl(struct file *filep, unsigned 
int cmd,
 
/* TX settings */
case LIRC_SET_TRANSMITTER_MASK:
-   if (!dev-s_tx_mask)
-   return -EINVAL;
+   if (dev-s_tx_mask)
+   return dev-s_tx_mask(dev, val);
 
-   return dev-s_tx_mask(dev, val);
+   if (dev-get_ir_tx  dev-set_ir_tx) {
+   memset(tx, 0, sizeof(tx));
+   dev-get_ir_tx(dev, tx);
+   tx.tx_enabled = val;
+   return dev-set_ir_tx(dev, tx);
+   }
+
+   return -EINVAL;
 
case LIRC_SET_SEND_CARRIER:
-   if (!dev-s_tx_carrier)
-   return -EINVAL;
+   if (dev-s_tx_carrier)
+   return dev-s_tx_carrier(dev, val);
 
-   return dev-s_tx_carrier(dev, val);
+   if (dev-get_ir_tx  dev-set_ir_tx) {
+   memset(tx, 0, sizeof(tx));
+   dev-get_ir_tx(dev, tx);
+   tx.freq = val;
+   return dev-set_ir_tx(dev, tx);
+   }
 
-   case LIRC_SET_SEND_DUTY_CYCLE:
-   if (!dev-s_tx_duty_cycle)
-   return -ENOSYS;
+   return -EINVAL;
 
+   case LIRC_SET_SEND_DUTY_CYCLE:
if (val = 0 || val = 100)
return -EINVAL;
 
-   return dev-s_tx_duty_cycle(dev, val);
+   if (dev-s_tx_duty_cycle)
+   return dev-s_tx_duty_cycle(dev, val);
+
+   if (dev-get_ir_tx  dev-set_ir_tx) {
+   memset(tx, 0, sizeof(tx));
+   dev-get_ir_tx(dev, tx);
+   tx.duty = val;
+   return dev-set_ir_tx(dev, tx);
+   }
+
+   return -ENOSYS;
 
/* RX settings */
case LIRC_SET_REC_CARRIER:
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index e2b2e8c..f8a63e2 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1742,6 +1742,19 @@ static long rc_do_ioctl(struct rc_dev *dev, unsigned int 
cmd, unsigned long arg)
 
return 0;
 
+   case RCIOCSIRTX:
+   if (!dev-set_ir_tx)
+   return -ENOSYS;
+
+   if (copy_from_user(tx, p, sizeof(tx)))
+   return -EFAULT;
+
+   error = dev-set_ir_tx(dev, tx);
+   if (error)
+   return error;
+
+   /* Fall through */
+
case RCIOCGIRTX:
memset(tx, 0, sizeof(tx));
 
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index 9f3645b..843f363 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -115,8 +115,11 @@ struct rc_ir_rx {
 /* get ir tx parameters */
 #define RCIOCGIRTX _IOC(_IOC_READ, RC_IOC_MAGIC, 0x05, sizeof(struct 
rc_ir_tx))
 
+/* set ir tx parameters */
+#define RCIOCSIRTX _IOC(_IOC_WRITE, RC_IOC_MAGIC, 0x05, sizeof(struct 
rc_ir_tx))
+
 /**
- * struct rc_ir_tx - used to get all IR TX parameters in one go
+ * struct rc_ir_tx - used to get/set all IR TX parameters in one go
  * @flags: device specific flags
  * @tx_supported: bitmask of supported transmitters
  * @tx_enabled: bitmask of enabled transmitters
@@ -238,9 +241,9 @@ struct ir_raw_event {
  * is opened.
  * @close: callback to allow drivers to disable polling/irq when IR input 
device
  * is opened.
- * @s_tx_mask: set transmitter mask (for devices with multiple tx outputs)
- * @s_tx_carrier: set transmit carrier frequency
- * @s_tx_duty_cycle: set transmit duty cycle (0% - 100%)
+ * @s_tx_mask: set transmitter mask (for devices with multiple tx outputs, 

[PATCH 10/43] rc-core: allow chardev to be read

2012-05-23 Thread David Härdeman
This patch is the first step towards making the rc chardev usable by adding
read functionality.

Basically the implementation mimics what evdev does. Userspace applications can
open the rc device and read rc_event structs with data. Only some basic events
are supported for now but later patches will add further events.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-main.c |  134 +++-
 include/media/rc-core.h|   31 ++
 2 files changed, 163 insertions(+), 2 deletions(-)

diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index d7a50b6..ef8d358 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -20,6 +20,7 @@
 #include linux/sched.h
 #include linux/device.h
 #include linux/module.h
+#include linux/poll.h
 #include rc-core-priv.h
 
 /* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
@@ -52,11 +53,66 @@ static DEFINE_MUTEX(rc_dev_table_mutex);
 struct rc_client {
struct rc_dev *dev;
spinlock_t rxlock;
-   DECLARE_KFIFO(rxfifo, int, RC_RX_BUFFER_SIZE);
+   DECLARE_KFIFO(rxfifo, struct rc_event, RC_RX_BUFFER_SIZE);
struct fasync_struct *fasync;
struct list_head node;
 };
 
+/**
+ * rc_client_event() - passes an rc event to a specific client
+ * @client:the struct rc_client for this client
+ * @type:  the event type
+ * @code:  the event code (type specific)
+ * @val:   the event value (type and code specific)
+ *
+ * This function writes a struct rc_event entry to the client kfifo
+ * for later reading from userspace.
+ */
+static void rc_client_event(struct rc_client *client, u16 type,
+   u16 code, u64 val)
+{
+   unsigned long flags;
+   struct rc_event event;
+
+   event.type = type;
+   event.code = code;
+   event.reserved = 0;
+   event.val = val;
+
+   spin_lock_irqsave(client-rxlock, flags);
+   if (kfifo_is_full(client-rxfifo)) {
+   kfifo_skip(client-rxfifo);
+   event.type = RC_CORE;
+   event.code = RC_CORE_DROPPED;
+   event.val = 1;
+   }
+   kfifo_in(client-rxfifo, event, 1);
+   kill_fasync(client-fasync, SIGIO, POLL_IN);
+   spin_unlock_irqrestore(client-rxlock, flags);
+}
+
+/**
+ * rc_event() - sends an rc_event to all listeners
+ * @dev:   the struct rc_dev of the device generating the event
+ * @type:  the event type
+ * @code:  the event code (type specific)
+ * @val:   the event value (type and code specific)
+ *
+ * This function passes an rc event to all clients.
+ */
+void rc_event(struct rc_dev *dev, u16 type, u16 code, u64 val)
+{
+   struct rc_client *client;
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(client, dev-client_list, node)
+   rc_client_event(client, type, code, val);
+   rcu_read_unlock();
+
+   wake_up_interruptible(dev-rxwait);
+}
+EXPORT_SYMBOL_GPL(rc_event);
+
 static struct rc_map_list *seek_rc_map(const char *name)
 {
struct rc_map_list *map = NULL;
@@ -719,6 +775,7 @@ void rc_repeat(struct rc_dev *dev)
 
input_event(dev-input_dev, EV_MSC, MSC_SCAN, dev-last_scancode);
input_sync(dev-input_dev);
+   rc_event(dev, RC_KEY, RC_KEY_REPEAT, 1);
 
if (!dev-keypressed)
goto out;
@@ -754,6 +811,9 @@ static void ir_do_keydown(struct rc_dev *dev, u16 protocol,
ir_do_keyup(dev, false);
 
input_event(dev-input_dev, EV_MSC, MSC_SCAN, scancode);
+   rc_event(dev, RC_KEY, RC_KEY_PROTOCOL, protocol);
+   rc_event(dev, RC_KEY, RC_KEY_SCANCODE, scancode);
+   rc_event(dev, RC_KEY, RC_KEY_TOGGLE, toggle);
 
if (new_event  keycode != KEY_RESERVED) {
/* Register a keypress */
@@ -1147,7 +1207,7 @@ struct rc_dev *rc_allocate_device(void)
 
INIT_LIST_HEAD(dev-client_list);
spin_lock_init(dev-client_lock);
-
+   init_waitqueue_head(dev-rxwait);
spin_lock_init(dev-rc_map.lock);
spin_lock_init(dev-keylock);
mutex_init(dev-lock);
@@ -1338,6 +1398,7 @@ void rc_unregister_device(struct rc_dev *dev)
list_for_each_entry(client, dev-client_list, node)
kill_fasync(client-fasync, SIGIO, POLL_HUP);
spin_unlock(dev-client_lock);
+   wake_up_interruptible_all(dev-rxwait);
 
del_timer_sync(dev-timer_keyup);
 
@@ -1441,6 +1502,73 @@ static int rc_release(struct inode *inode, struct file 
*file)
 }
 
 /**
+ * rc_read() - allows userspace to read rc events
+ * @file:  the struct file corresponding to the previous open()
+ * @buffer:the userspace buffer to read data to
+ * @count: the number of bytes to read
+ * @ppos:  the file offset
+ * @return:the number of bytes read, or a negative error code
+ *
+ * This function (which implements read in struct file_operations)
+ * allows userspace to read events from the rc device file.
+ 

[PATCH 12/43] redrat: cleanup debug functions

2012-05-23 Thread David Härdeman
In preparation for the next patches I had to understand the redrat driver (not
an easy task).

In the process I noticed that the debug printing functions look quite
suspicious. This is a minimal attempt at cleaning them up (though more work
remains to be done).

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/redrat3.c |   40 +++-
 1 file changed, 23 insertions(+), 17 deletions(-)

diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index 13a679f..46137b8 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -252,25 +252,29 @@ static void redrat3_dump_signal_header(struct 
redrat3_signal_header *header)
pr_info( * repeats: %u\n, header-no_repeats);
 }
 
-static void redrat3_dump_signal_data(char *buffer, u16 len)
+static void redrat3_dump_signal_lens(u16 *buf, u8 n)
 {
-   int offset, i;
-   char *data_vals;
+   unsigned i;
 
pr_info(%s:, __func__);
+   for (i = 0; i  n; i++) {
+   if (i % 10 == 0)
+   pr_cont(\n * );
+   pr_cont(%02x , buf[i]);
+   }
+   pr_cont(\n);
+}
 
-   offset = RR3_TX_HEADER_OFFSET + RR3_HEADER_LENGTH
-+ (RR3_DRIVER_MAXLENS * sizeof(u16));
-
-   /* read RR3_DRIVER_MAXLENS from ctrl msg */
-   data_vals = buffer + offset;
+static void redrat3_dump_signal_data(u8 *buf, u16 n)
+{
+   unsigned i;
 
-   for (i = 0; i  len; i++) {
+   pr_info(%s:, __func__);
+   for (i = 0; i  n; i++) {
if (i % 10 == 0)
pr_cont(\n * );
-   pr_cont(%02x , *data_vals++);
+   pr_cont(%02x , buf[i]);
}
-
pr_cont(\n);
 }
 
@@ -466,11 +470,6 @@ static void redrat3_process_ir_data(struct redrat3_dev 
*rr3)
 
header.no_repeats= sig_data[RR3_REPEATS_OFFSET];
 
-   if (debug) {
-   redrat3_dump_signal_header(header);
-   redrat3_dump_signal_data(sig_data, header.sig_size);
-   }
-
mod_freq = redrat3_val_to_mod_freq(header);
rr3_dbg(dev, Got mod_freq of %u\n, mod_freq);
 
@@ -480,6 +479,12 @@ static void redrat3_process_ir_data(struct redrat3_dev 
*rr3)
data_vals = sig_data + RR3_HEADER_LENGTH +
(header.max_lengths * sizeof(u16));
 
+   if (debug) {
+   redrat3_dump_signal_header(header);
+   redrat3_dump_signal_lens(len_vals, header.no_lengths);
+   redrat3_dump_signal_data(data_vals, header.sig_size);
+   }
+
/* process each rr3 encoded byte into an int */
for (i = 0; i  header.sig_size; i++) {
u16 val = len_vals[data_vals[i]];
@@ -1022,7 +1027,8 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, 
unsigned *txbuf,
 
if (debug) {
redrat3_dump_signal_header(header);
-   redrat3_dump_signal_data(buffer, header.sig_size);
+   redrat3_dump_signal_lens(lengths_ptr, curlencheck);
+   redrat3_dump_signal_data(sigdata, count);
}
 
pipe = usb_sndbulkpipe(rr3-udev, rr3-ep_out-bEndpointAddress);

--
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 23/43] rc-loopback: add RCIOCSIRTX ioctl support

2012-05-23 Thread David Härdeman
As an example, this patch adds support for the new RCIOCSIRTX ioctl
to rc-loopback and removes deprecated functions without a loss in
functionality (as LIRC will automatically use the new functions).

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-loopback.c |   59 +---
 1 file changed, 19 insertions(+), 40 deletions(-)

diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
index a04b39b..de9a75e 100644
--- a/drivers/media/rc/rc-loopback.c
+++ b/drivers/media/rc/rc-loopback.c
@@ -49,43 +49,6 @@ struct loopback_dev {
 
 static struct loopback_dev loopdev;
 
-static int loop_set_tx_mask(struct rc_dev *dev, u32 mask)
-{
-   struct loopback_dev *lodev = dev-priv;
-
-   if ((mask  (RXMASK_REGULAR | RXMASK_LEARNING)) != mask) {
-   dprintk(invalid tx mask: %u\n, mask);
-   return -EINVAL;
-   }
-
-   dprintk(setting tx mask: %u\n, mask);
-   lodev-txmask = mask;
-   return 0;
-}
-
-static int loop_set_tx_carrier(struct rc_dev *dev, u32 carrier)
-{
-   struct loopback_dev *lodev = dev-priv;
-
-   dprintk(setting tx carrier: %u\n, carrier);
-   lodev-txcarrier = carrier;
-   return 0;
-}
-
-static int loop_set_tx_duty_cycle(struct rc_dev *dev, u32 duty_cycle)
-{
-   struct loopback_dev *lodev = dev-priv;
-
-   if (duty_cycle  1 || duty_cycle  99) {
-   dprintk(invalid duty cycle: %u\n, duty_cycle);
-   return -EINVAL;
-   }
-
-   dprintk(setting duty cycle: %u\n, duty_cycle);
-   lodev-txduty = duty_cycle;
-   return 0;
-}
-
 static int loop_tx_ir(struct rc_dev *dev)
 {
struct loopback_dev *lodev = dev-priv;
@@ -221,6 +184,24 @@ static void loop_get_ir_tx(struct rc_dev *dev, struct 
rc_ir_tx *tx)
tx-resolution_max = 1;
 }
 
+/**
+ * loop_set_ir_tx() - changes and returns the current TX settings
+ * @dev: the struct rc_dev to change the settings for
+ * @tx: the struct rc_ir_tx with the new settings
+ *
+ * This function is used to change and return the current TX settings.
+ */
+static int loop_set_ir_tx(struct rc_dev *dev, struct rc_ir_tx *tx)
+{
+   struct loopback_dev *lodev = dev-priv;
+
+   lodev-txmask = tx-tx_enabled  (RXMASK_REGULAR | RXMASK_LEARNING);
+   lodev-txcarrier = tx-freq;
+   lodev-txduty = tx-duty;
+
+   return 0;
+}
+
 static int __init loop_init(void)
 {
struct rc_dev *rc;
@@ -246,14 +227,12 @@ static int __init loop_init(void)
rc-max_timeout = UINT_MAX;
rc-rx_resolution   = 1000;
rc-tx_resolution   = 1000;
-   rc-s_tx_mask   = loop_set_tx_mask;
-   rc-s_tx_carrier= loop_set_tx_carrier;
-   rc-s_tx_duty_cycle = loop_set_tx_duty_cycle;
rc-tx_ir   = loop_tx_ir;
rc-s_idle  = loop_set_idle;
rc-get_ir_rx   = loop_get_ir_rx;
rc-set_ir_rx   = loop_set_ir_rx;
rc-get_ir_tx   = loop_get_ir_tx;
+   rc-set_ir_tx   = loop_set_ir_tx;
 
loopdev.txmask  = RXMASK_REGULAR;
loopdev.txcarrier   = 36000;

--
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 37/43] rc-core: don't report scancodes via input devices

2012-05-23 Thread David Härdeman
The scancode that is reported via the input device(s) is now incomplete
(missing the protocol) and redundant.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-keytable.c |   21 +
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/media/rc/rc-keytable.c b/drivers/media/rc/rc-keytable.c
index 84c6e96..d0777cb 100644
--- a/drivers/media/rc/rc-keytable.c
+++ b/drivers/media/rc/rc-keytable.c
@@ -611,17 +611,10 @@ void rc_keytable_repeat(struct rc_keytable *kt)
unsigned long flags;
 
spin_lock_irqsave(kt-key_lock, flags);
-
-   input_event(kt-idev, EV_MSC, MSC_SCAN, kt-last_scancode);
-   input_sync(kt-idev);
-
-   if (!kt-key_pressed)
-   goto out;
-
-   kt-keyup_jiffies = jiffies + msecs_to_jiffies(RC_KEYPRESS_TIMEOUT);
-   mod_timer(kt-timer_keyup, kt-keyup_jiffies);
-
-out:
+   if (kt-key_pressed) {
+   kt-keyup_jiffies = jiffies + 
msecs_to_jiffies(RC_KEYPRESS_TIMEOUT);
+   mod_timer(kt-timer_keyup, kt-keyup_jiffies);
+   }
spin_unlock_irqrestore(kt-key_lock, flags);
 }
 
@@ -660,8 +653,6 @@ void rc_keytable_keydown(struct rc_keytable *kt, enum 
rc_type protocol,
if (new_event)
rc_do_keyup(kt, false);
 
-   input_event(kt-idev, EV_MSC, MSC_SCAN, scancode);
-
if (new_event  keycode != KEY_RESERVED) {
/* Register a keypress */
kt-key_pressed = true;
@@ -675,8 +666,8 @@ void rc_keytable_keydown(struct rc_keytable *kt, enum 
rc_type protocol,
   kt-dev-input_name, keycode, protocol,
   (long long unsigned)scancode);
input_report_key(kt-idev, keycode, 1);
+   input_sync(kt-idev);
}
-   input_sync(kt-idev);
 
if (autoup  kt-key_pressed) {
kt-keyup_jiffies = jiffies + 
msecs_to_jiffies(RC_KEYPRESS_TIMEOUT);
@@ -799,8 +790,6 @@ struct rc_keytable *rc_keytable_create(struct rc_dev *dev,
idev-close = rc_input_close;
set_bit(EV_KEY, idev-evbit);
set_bit(EV_REP, idev-evbit);
-   set_bit(EV_MSC, idev-evbit);
-   set_bit(MSC_SCAN, idev-mscbit);
input_set_drvdata(idev, kt);
setup_timer(kt-timer_keyup, rc_timer_keyup, (unsigned long)kt);
 

--
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/43] rc-core: initialize rc-core earlier if built-in

2012-05-23 Thread David Härdeman
rc-core is a subsystem so it should be registered earlier if built into the
kernel.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-main.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 0e50a84..6e02314 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1302,7 +1302,7 @@ static void __exit rc_core_exit(void)
rc_map_unregister(empty_map);
 }
 
-module_init(rc_core_init);
+subsys_initcall(rc_core_init);
 module_exit(rc_core_exit);
 
 int rc_core_debug;/* ir_debug level (0,1,2) */

--
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 05/43] rc-core: merge rc5 and streamzap decoders

2012-05-23 Thread David Härdeman
Now that the protocol is part of the scancode, it is pretty easy to merge
the rc5 and streamzap decoders. An additional advantage is that the decoder
is now stricter as it waits for the trailing silence before determining that
a command is a valid rc5/streamzap command (which avoids collisions that I've
seen with e.g. Sony protocols).

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/Kconfig|   12 --
 drivers/media/rc/Makefile   |1 
 drivers/media/rc/ir-rc5-decoder.c   |   51 ++
 drivers/media/rc/ir-rc5-sz-decoder.c|  154 ---
 drivers/media/rc/keymaps/rc-streamzap.c |4 -
 drivers/media/rc/rc-core-priv.h |8 --
 drivers/media/rc/streamzap.c|   10 --
 7 files changed, 31 insertions(+), 209 deletions(-)
 delete mode 100644 drivers/media/rc/ir-rc5-sz-decoder.c

diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index f97eeb8..090872b 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -76,18 +76,6 @@ config IR_SONY_DECODER
   Enable this option if you have an infrared remote control which
   uses the Sony protocol, and you need software decoding support.
 
-config IR_RC5_SZ_DECODER
-   tristate Enable IR raw decoder for the RC-5 (streamzap) protocol
-   depends on RC_CORE
-   select BITREVERSE
-   default y
-
-   ---help---
-  Enable this option if you have IR with RC-5 (streamzap) protocol,
-  and if the IR is decoded in software. (The Streamzap PC Remote
-  uses an IR protocol that is almost standard RC-5, but not quite,
-  as it uses an additional bit).
-
 config IR_SANYO_DECODER
tristate Enable IR raw decoder for the Sanyo protocol
depends on RC_CORE
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 29f364f..596060a 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -9,7 +9,6 @@ obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
 obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
 obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
 obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
-obj-$(CONFIG_IR_RC5_SZ_DECODER) += ir-rc5-sz-decoder.o
 obj-$(CONFIG_IR_SANYO_DECODER) += ir-sanyo-decoder.o
 obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o
 obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
diff --git a/drivers/media/rc/ir-rc5-decoder.c 
b/drivers/media/rc/ir-rc5-decoder.c
index ddbf9bf..9594b8f 100644
--- a/drivers/media/rc/ir-rc5-decoder.c
+++ b/drivers/media/rc/ir-rc5-decoder.c
@@ -1,6 +1,7 @@
-/* ir-rc5-decoder.c - handle RC5(x) IR Pulse/Space protocol
+/* ir-rc5-decoder.c - decoder for RC5(x) and StreamZap protocols
  *
  * Copyright (C) 2010 by Mauro Carvalho Chehab mche...@redhat.com
+ * Copyright (C) 2010 by Jarod Wilson ja...@redhat.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
@@ -13,23 +14,22 @@
  */
 
 /*
- * This code handles 14 bits RC5 protocols and 20 bits RC5x protocols.
- * There are other variants that use a different number of bits.
- * This is currently unsupported.
- * It considers a carrier of 36 kHz, with a total of 14/20 bits, where
- * the first two bits are start bits, and a third one is a filing bit
+ * This decoder handles the 14 bit RC5 protocol, 15 bit StreamZap protocol
+ * and 20 bit RC5x protocol.
  */
 
 #include rc-core-priv.h
 #include linux/module.h
 
 #define RC5_NBITS  14
+#define RC5_SZ_NBITS   15
 #define RC5X_NBITS 20
 #define CHECK_RC5X_NBITS   8
 #define RC5_UNIT   88 /* ns */
 #define RC5_BIT_START  (1 * RC5_UNIT)
 #define RC5_BIT_END(1 * RC5_UNIT)
 #define RC5X_SPACE (4 * RC5_UNIT)
+#define RC5_TRAILER(10 * RC5_UNIT) /* In reality, approx 100 */
 
 enum rc5_state {
STATE_INACTIVE,
@@ -80,12 +80,15 @@ again:
 
data-state = STATE_BIT_START;
data-count = 1;
-   /* We just need enough bits to get to STATE_CHECK_RC5X */
-   data-wanted_bits = RC5X_NBITS;
decrease_duration(ev, RC5_BIT_START);
goto again;
 
case STATE_BIT_START:
+   if (!ev.pulse  geq_margin(ev.duration, RC5_TRAILER, RC5_UNIT 
/ 2)) {
+   data-state = STATE_FINISHED;
+   goto again;
+   }
+
if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
break;
 
@@ -100,9 +103,7 @@ again:
if (!is_transition(ev, dev-raw-prev_ev))
break;
 
-   if (data-count == data-wanted_bits)
-   data-state = STATE_FINISHED;
-   else if (data-count == CHECK_RC5X_NBITS)
+   if (data-count == CHECK_RC5X_NBITS)
data-state 

[PATCH 30/43] rc-core: make keytable RCU-friendly

2012-05-23 Thread David Härdeman
Change struct rc_keytable to be RCU-friendly by kmalloc():ing an
entire new scancode,protocol - keycode table every time the table
is changed (i.e. via EVIOCSKEYCODE(_V2)).

The advantage is that the performance-critical keycode lookup path
can be made entirely lock-free and that GFP_ATOMIC allocations
can be avoided entirely at the cost of a couple of extra kmalloc()
calls when changing a keytable (which is normally done once during
boot).

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-keytable.c |  671 +++-
 include/media/rc-core.h|   32 +-
 2 files changed, 334 insertions(+), 369 deletions(-)

diff --git a/drivers/media/rc/rc-keytable.c b/drivers/media/rc/rc-keytable.c
index eb48358..d6e68d0 100644
--- a/drivers/media/rc/rc-keytable.c
+++ b/drivers/media/rc/rc-keytable.c
@@ -24,12 +24,10 @@
 #include linux/poll.h
 #include rc-core-priv.h
 
-/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
-#define RC_TAB_MIN_SIZE256
-#define RC_TAB_MAX_SIZE8192
+#define RC_TAB_MAX_SIZE1024 /* entries */
 
-/* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */
-#define IR_KEYPRESS_TIMEOUT 250
+/* FIXME: RC_KEYPRESS_TIMEOUT should be protocol specific */
+#define RC_KEYPRESS_TIMEOUT 250
 
 /* Used to keep track of known keymaps */
 static LIST_HEAD(rc_map_list);
@@ -98,248 +96,238 @@ void rc_map_unregister(struct rc_map_list *map)
 EXPORT_SYMBOL_GPL(rc_map_unregister);
 
 /**
- * ir_create_table() - initializes a scancode table
- * @rc_map:the rc_map to initialize
- * @name:  name to assign to the table
- * @size:  initial size of the table
- * @return:zero on success or a negative error code
- *
- * This routine will initialize the rc_map and will allocate
- * memory to hold at least the specified number of elements.
+ * rc_scan_size() - determine the necessary size for a rc_scan struct
+ * @len:   the number of keytable entries the struct should hold
+ * @return:the size of the struct in bytes
  */
-static int ir_create_table(struct rc_map *rc_map,
-  const char *name, size_t size)
+static inline size_t rc_scan_size(unsigned len)
 {
-   rc_map-name = name;
-   rc_map-alloc = roundup_pow_of_two(size * sizeof(struct rc_map_table));
-   rc_map-size = rc_map-alloc / sizeof(struct rc_map_table);
-   rc_map-scan = kmalloc(rc_map-alloc, GFP_KERNEL);
-   if (!rc_map-scan)
-   return -ENOMEM;
-
-   IR_dprintk(1, Allocated space for %u keycode entries (%u bytes)\n,
-  rc_map-size, rc_map-alloc);
-   return 0;
+   return sizeof(struct rc_scan) + len * sizeof(struct rc_map_table);
 }
 
 /**
- * ir_free_table() - frees memory allocated by a scancode table
- * @rc_map:the table whose mappings need to be freed
+ * rc_keytable_update_entry() - update an existing entry in the keytable
+ * @kt:the keytable to update
+ * @i: the index of the entry to update
+ * @entry: the new values for the entry
+ * @return:the old rc_scan struct, NULL if memory could not be allocated
  *
- * This routine will free memory alloctaed for key mappings used by given
- * scancode table.
+ * Updates a keytable by replacing an existing entry at the given index.
+ * The old rc_scan struct is returned so that it can be freed at a
+ * later stage.
  */
-static void ir_free_table(struct rc_map *rc_map)
+static struct rc_scan *rc_keytable_update_entry(struct rc_keytable *kt,
+   unsigned i,
+   struct rc_map_table *entry)
 {
-   rc_map-size = 0;
-   kfree(rc_map-scan);
-   rc_map-scan = NULL;
-}
+   struct rc_scan *old_scan = kt-scan;
+   struct rc_scan *new_scan = kt-scan;
+   u32 old_keycode;
 
-/**
- * ir_resize_table() - resizes a scancode table if necessary
- * @rc_map:the rc_map to resize
- * @gfp_flags: gfp flags to use when allocating memory
- * @return:zero on success or a negative error code
- *
- * This routine will shrink the rc_map if it has lots of
- * unused entries and grow it if it is full.
- */
-static int ir_resize_table(struct rc_map *rc_map, gfp_t gfp_flags)
-{
-   unsigned int oldalloc = rc_map-alloc;
-   unsigned int newalloc = oldalloc;
-   struct rc_map_table *oldscan = rc_map-scan;
-   struct rc_map_table *newscan;
-
-   if (rc_map-size == rc_map-len) {
-   /* All entries in use - grow keytable */
-   if (rc_map-alloc = RC_TAB_MAX_SIZE)
-   return -ENOMEM;
-
-   newalloc *= 2;
-   IR_dprintk(1, Growing table to %u bytes\n, newalloc);
-   }
+   if (i = old_scan-len)
+   return NULL;
 
-   if ((rc_map-len * 3  rc_map-size)  (oldalloc  RC_TAB_MIN_SIZE)) {
-   /* Less than 1/3 of entries in use - shrink keytable */
-   

[PATCH 19/43] rc-loopback: add RCIOCSIRRX ioctl support

2012-05-23 Thread David Härdeman
As an example, this patch adds support for the new RCIOCSIRRX ioctl
to rc-loopback and removes deprecated functions without a loss in
functionality (as LIRC will automatically use the new functions).

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-loopback.c |   84 
 1 file changed, 42 insertions(+), 42 deletions(-)

diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c
index 7977b75..6d0e9fb 100644
--- a/drivers/media/rc/rc-loopback.c
+++ b/drivers/media/rc/rc-loopback.c
@@ -86,21 +86,6 @@ static int loop_set_tx_duty_cycle(struct rc_dev *dev, u32 
duty_cycle)
return 0;
 }
 
-static int loop_set_rx_carrier_range(struct rc_dev *dev, u32 min, u32 max)
-{
-   struct loopback_dev *lodev = dev-priv;
-
-   if (min  1 || min  max) {
-   dprintk(invalid rx carrier range %u to %u\n, min, max);
-   return -EINVAL;
-   }
-
-   dprintk(setting rx carrier range %u to %u\n, min, max);
-   lodev-rxcarriermin = min;
-   lodev-rxcarriermax = max;
-   return 0;
-}
-
 static int loop_tx_ir(struct rc_dev *dev)
 {
struct loopback_dev *lodev = dev-priv;
@@ -149,30 +134,6 @@ static void loop_set_idle(struct rc_dev *dev, bool enable)
}
 }
 
-static int loop_set_learning_mode(struct rc_dev *dev, int enable)
-{
-   struct loopback_dev *lodev = dev-priv;
-
-   if (lodev-learning != enable) {
-   dprintk(%sing learning mode\n, enable ? enter : exit);
-   lodev-learning = !!enable;
-   }
-
-   return 0;
-}
-
-static int loop_set_carrier_report(struct rc_dev *dev, int enable)
-{
-   struct loopback_dev *lodev = dev-priv;
-
-   if (lodev-carrierreport != enable) {
-   dprintk(%sabling carrier reports\n, enable ? en : dis);
-   lodev-carrierreport = !!enable;
-   }
-
-   return 0;
-}
-
 /**
  * loop_get_ir_rx() - returns the current RX settings
  * @dev: the struct rc_dev to get the settings for
@@ -194,6 +155,47 @@ static void loop_get_ir_rx(struct rc_dev *dev, struct 
rc_ir_rx *rx)
rx-duty_max = 99;
 }
 
+/**
+ * loop_set_ir_rx() - changes and returns the current RX settings
+ * @dev: the struct rc_dev to change the settings for
+ * @rx: the struct rc_ir_rx with the new settings
+ *
+ * This function is used to change and return the current RX settings.
+ */
+static int loop_set_ir_rx(struct rc_dev *dev, struct rc_ir_rx *rx)
+{
+   struct loopback_dev *lodev = dev-priv;
+
+   dprintk(%s called\n, __func__);
+   if (lodev-rxcarriermin != rx-freq_min) {
+   dprintk(changing rx carrier min to %u\n, rx-freq_min);
+   lodev-rxcarriermin = rx-freq_min;
+   }
+
+   if (lodev-rxcarriermax != rx-freq_max) {
+   dprintk(changing rx carrier max to %u\n, rx-freq_max);
+   lodev-rxcarriermax = rx-freq_max;
+   }
+
+   if (lodev-carrierreport == !(rx-flags  RC_IR_RX_MEASURE_CARRIER)) {
+   lodev-carrierreport = !!(rx-flags  RC_IR_RX_MEASURE_CARRIER);
+   dprintk(%sabling carrier reports\n,
+   lodev-carrierreport ? en : dis);
+   }
+
+   if ((rx-rx_enabled == RXMASK_LEARNING)  !lodev-learning) {
+   dprintk(enabling learning mode\n);
+   lodev-learning = true;
+   } else if ((rx-rx_enabled == RXMASK_REGULAR)  lodev-learning) {
+   dprintk(disabling learning mode\n);
+   lodev-learning = false;
+   }
+
+   /* Fill in the correct values after the changes */
+   loop_get_ir_rx(dev, rx);
+   return 0;
+}
+
 static int __init loop_init(void)
 {
struct rc_dev *rc;
@@ -222,12 +224,10 @@ static int __init loop_init(void)
rc-s_tx_mask   = loop_set_tx_mask;
rc-s_tx_carrier= loop_set_tx_carrier;
rc-s_tx_duty_cycle = loop_set_tx_duty_cycle;
-   rc-s_rx_carrier_range  = loop_set_rx_carrier_range;
rc-tx_ir   = loop_tx_ir;
rc-s_idle  = loop_set_idle;
-   rc-s_learning_mode = loop_set_learning_mode;
-   rc-s_carrier_report= loop_set_carrier_report;
rc-get_ir_rx   = loop_get_ir_rx;
+   rc-set_ir_rx   = loop_set_ir_rx;
 
loopdev.txmask  = RXMASK_REGULAR;
loopdev.txcarrier   = 36000;

--
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 20/43] rc-core: add an ioctl for getting IR TX settings

2012-05-23 Thread David Härdeman
This ioctl follows the same rationale and structure as the ioctl for
getting IR RX settings (RCIOCGIRRX) but it works on TX settings instead.

As with the RX ioctl, it would be nice if people could check struct
rc_ir_tx carefully to make sure that their favourite parameter
hasn't been left out.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-main.c |   12 
 include/media/rc-core.h|   38 ++
 2 files changed, 50 insertions(+)

diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 390673c..e2b2e8c 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1703,6 +1703,7 @@ static long rc_do_ioctl(struct rc_dev *dev, unsigned int 
cmd, unsigned long arg)
void __user *p = (void __user *)arg;
unsigned int __user *ip = (unsigned int __user *)p;
struct rc_ir_rx rx;
+   struct rc_ir_tx tx;
int error;
 
switch (cmd) {
@@ -1740,6 +1741,17 @@ static long rc_do_ioctl(struct rc_dev *dev, unsigned int 
cmd, unsigned long arg)
return -EFAULT;
 
return 0;
+
+   case RCIOCGIRTX:
+   memset(tx, 0, sizeof(tx));
+
+   if (dev-get_ir_tx)
+   dev-get_ir_tx(dev, tx);
+
+   if (copy_to_user(p, tx, sizeof(tx)))
+   return -EFAULT;
+
+   return 0;
}
 
return -EINVAL;
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index 213b642..9f3645b 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -112,6 +112,42 @@ struct rc_ir_rx {
__u32 reserved[9];
 } __packed;
 
+/* get ir tx parameters */
+#define RCIOCGIRTX _IOC(_IOC_READ, RC_IOC_MAGIC, 0x05, sizeof(struct 
rc_ir_tx))
+
+/**
+ * struct rc_ir_tx - used to get all IR TX parameters in one go
+ * @flags: device specific flags
+ * @tx_supported: bitmask of supported transmitters
+ * @tx_enabled: bitmask of enabled transmitters
+ * @tx_connected: bitmask of connected transmitters
+ * @freq: current carrier frequency
+ * @freq_min: min carrier frequency
+ * @freq_max: max carrier frequency
+ * @duty: current duty cycle
+ * @duty_min: min duty cycle
+ * @duty_max: max duty cycle
+ * @resolution: current resolution
+ * @resolution_min: min resolution
+ * @resolution_max: max resolution
+ * @reserved: for future use, set to zero
+ */
+struct rc_ir_tx {
+   __u32 flags;
+   __u32 tx_supported;
+   __u32 tx_enabled;
+   __u32 tx_connected;
+   __u32 freq;
+   __u32 freq_min;
+   __u32 freq_max;
+   __u32 duty;
+   __u32 duty_min;
+   __u32 duty_max;
+   __u32 resolution;
+   __u32 resolution_min;
+   __u32 resolution_max;
+   __u32 reserved[9];
+} __packed;
 
 
 enum rc_driver_type {
@@ -213,6 +249,7 @@ struct ir_raw_event {
  * @s_carrier_report: enable carrier reports (deprecated)
  * @get_ir_rx: allow driver to provide rx settings
  * @set_ir_rx: allow driver to change rx settings
+ * @get_ir_tx: allow driver to provide tx settings
  */
 struct rc_dev {
struct device   dev;
@@ -265,6 +302,7 @@ struct rc_dev {
int (*s_carrier_report) (struct rc_dev 
*dev, int enable);
void(*get_ir_rx)(struct rc_dev *dev, struct 
rc_ir_rx *rx);
int (*set_ir_rx)(struct rc_dev *dev, struct 
rc_ir_rx *rx);
+   void(*get_ir_tx)(struct rc_dev *dev, struct 
rc_ir_tx *tx);
 };
 
 #define to_rc_dev(d) container_of(d, struct rc_dev, dev)

--
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 11/43] mceusb: remove pointless kmalloc

2012-05-23 Thread David Härdeman
The previous code allocated a char buffer of size MCE_CMDBUF_SIZE (384) by
kzalloc():ing sizeof(unsigned) * MCE_CMDBUF_SIZE bytes.

The buffer was therefore 4 * the necessary size.

Additionally, zeroing out the buffer is pointless.

Replace the allocated buffer with a stack buffer.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/mceusb.c |7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index f0f053d..9f546be 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -785,11 +785,7 @@ static int mceusb_tx_ir(struct rc_dev *dev, unsigned 
*txbuf, unsigned count)
struct mceusb_dev *ir = dev-priv;
int i, ret = 0;
int cmdcount = 0;
-   unsigned char *cmdbuf; /* MCE command buffer */
-
-   cmdbuf = kzalloc(sizeof(unsigned) * MCE_CMDBUF_SIZE, GFP_KERNEL);
-   if (!cmdbuf)
-   return -ENOMEM;
+   unsigned char cmdbuf[MCE_CMDBUF_SIZE]; /* MCE command buffer */
 
/* MCE tx init header */
cmdbuf[cmdcount++] = MCE_CMD_PORT_IR;
@@ -841,7 +837,6 @@ static int mceusb_tx_ir(struct rc_dev *dev, unsigned 
*txbuf, unsigned count)
mce_async_out(ir, cmdbuf, cmdcount);
 
 out:
-   kfree(cmdbuf);
return ret ? ret : count;
 }
 

--
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 08/43] rc-core: use a device table rather than an atomic number

2012-05-23 Thread David Härdeman
This patch changes rc-core to use a device table rather than atomic integers
to assign unique numbers to each rc device. This is in preparation for
introducing rc-core chardevs.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/ir-raw.c  |2 +-
 drivers/media/rc/rc-main.c |   41 +++--
 include/media/rc-core.h|4 ++--
 3 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c
index 6b3c9e5..7729abe 100644
--- a/drivers/media/rc/ir-raw.c
+++ b/drivers/media/rc/ir-raw.c
@@ -268,7 +268,7 @@ int ir_raw_event_register(struct rc_dev *dev)
 
spin_lock_init(dev-raw-lock);
dev-raw-thread = kthread_run(ir_raw_event_thread, dev-raw,
-  rc%ld, dev-devno);
+  rc%u, dev-minor);
 
if (IS_ERR(dev-raw-thread)) {
rc = PTR_ERR(dev-raw-thread);
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 6e02314..8da7701 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -24,6 +24,7 @@
 /* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
 #define IR_TAB_MIN_SIZE256
 #define IR_TAB_MAX_SIZE8192
+#define RC_DEV_MAX 32
 
 /* FIXME: IR_KEYPRESS_TIMEOUT should be protocol specific */
 #define IR_KEYPRESS_TIMEOUT 250
@@ -32,6 +33,10 @@
 static LIST_HEAD(rc_map_list);
 static DEFINE_SPINLOCK(rc_map_lock);
 
+/* Various bits and pieces to keep track of rc devices */
+static struct rc_dev *rc_dev_table[RC_DEV_MAX];
+static DEFINE_MUTEX(rc_dev_table_mutex);
+
 static struct rc_map_list *seek_rc_map(const char *name)
 {
struct rc_map_list *map = NULL;
@@ -1138,10 +1143,10 @@ EXPORT_SYMBOL_GPL(rc_free_device);
 int rc_register_device(struct rc_dev *dev)
 {
static bool raw_init = false; /* raw decoders loaded? */
-   static atomic_t devno = ATOMIC_INIT(0);
struct rc_map *rc_map;
const char *path;
int rc;
+   unsigned int i;
 
if (!dev || !dev-map_name)
return -EINVAL;
@@ -1161,6 +1166,26 @@ int rc_register_device(struct rc_dev *dev)
if (dev-close)
dev-input_dev-close = ir_close;
 
+   rc = mutex_lock_interruptible(rc_dev_table_mutex);
+   if (rc)
+   return rc;
+
+   for (i = 0; i  ARRAY_SIZE(rc_dev_table); i++) {
+   if (!rc_dev_table[i]) {
+   rc_dev_table[i] = dev;
+   break;
+   }
+   }
+
+   mutex_unlock(rc_dev_table_mutex);
+
+   if (i = ARRAY_SIZE(rc_dev_table))
+   return -ENFILE;
+
+   dev-minor = i;
+   dev_set_name(dev-dev, rc%u, dev-minor);
+   dev_set_drvdata(dev-dev, dev);
+
/*
 * Take the lock here, as the device sysfs node will appear
 * when device_add() is called, which may trigger an ir-keytable udev
@@ -1170,9 +1195,6 @@ int rc_register_device(struct rc_dev *dev)
 */
mutex_lock(dev-lock);
 
-   dev-devno = (unsigned long)(atomic_inc_return(devno) - 1);
-   dev_set_name(dev-dev, rc%ld, dev-devno);
-   dev_set_drvdata(dev-dev, dev);
rc = device_add(dev-dev);
if (rc)
goto out_unlock;
@@ -1231,8 +1253,8 @@ int rc_register_device(struct rc_dev *dev)
 
mutex_unlock(dev-lock);
 
-   IR_dprintk(1, Registered rc%ld (driver: %s, remote: %s, mode %s)\n,
-  dev-devno,
+   IR_dprintk(1, Registered rc%u (driver: %s, remote: %s, mode %s)\n,
+  dev-minor,
   dev-driver_name ? dev-driver_name : unknown,
   rc_map-name ? rc_map-name : unknown,
   dev-driver_type == RC_DRIVER_IR_RAW ? raw : cooked);
@@ -1251,6 +1273,9 @@ out_dev:
device_del(dev-dev);
 out_unlock:
mutex_unlock(dev-lock);
+   mutex_lock(rc_dev_table_mutex);
+   rc_dev_table[dev-minor] = NULL;
+   mutex_unlock(rc_dev_table_mutex);
return rc;
 }
 EXPORT_SYMBOL_GPL(rc_register_device);
@@ -1260,6 +1285,10 @@ void rc_unregister_device(struct rc_dev *dev)
if (!dev)
return;
 
+   mutex_lock(rc_dev_table_mutex);
+   rc_dev_table[dev-minor] = NULL;
+   mutex_unlock(rc_dev_table_mutex);
+
del_timer_sync(dev-timer_keyup);
 
if (dev-driver_type == RC_DRIVER_IR_RAW)
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index 0045292..1d4f5a0 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -63,7 +63,7 @@ struct rc_keymap_entry {
  * @rc_map: current scan/key table
  * @lock: used to ensure we've filled in all protocol details before
  * anyone can call show_protocols or store_protocols
- * @devno: unique remote control device number
+ * @minor: unique minor remote control device number
  * @raw: additional data for raw pulse/space devices
  * @input_dev: the input 

[PATCH 14/43] rc-core: allow chardev to be written

2012-05-23 Thread David Härdeman
Add write functionality to the rc chardev (for use in transmitting remote
control commands on capable hardware).

The data format of the TX data is probably going to have to be dependent
on the rc_driver_type.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/rc-main.c |   68 
 include/media/rc-core.h|2 +
 2 files changed, 70 insertions(+)

diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index 80d6dac..3389822 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1211,6 +1211,7 @@ struct rc_dev *rc_allocate_device(void)
INIT_KFIFO(dev-txfifo);
spin_lock_init(dev-txlock);
init_waitqueue_head(dev-rxwait);
+   init_waitqueue_head(dev-txwait);
spin_lock_init(dev-rc_map.lock);
spin_lock_init(dev-keylock);
mutex_init(dev-lock);
@@ -1409,6 +1410,7 @@ void rc_unregister_device(struct rc_dev *dev)
kill_fasync(client-fasync, SIGIO, POLL_HUP);
spin_unlock(dev-client_lock);
wake_up_interruptible_all(dev-rxwait);
+   wake_up_interruptible_all(dev-txwait);
 
del_timer_sync(dev-timer_keyup);
 
@@ -1560,6 +1562,69 @@ static ssize_t rc_read(struct file *file, char __user 
*buffer,
 }
 
 /**
+ * rc_write() - allows userspace to write data to transmit
+ * @file:  the struct file corresponding to the previous open()
+ * @buffer:the userspace buffer to read data from
+ * @count: the number of bytes to read
+ * @ppos:  the file offset
+ * @return:the number of bytes written, or a negative error code
+ *
+ * This function (which implements write in struct file_operations)
+ * allows userspace to transmit data using a suitable rc device
+ */
+static ssize_t rc_write(struct file *file, const char __user *buffer,
+   size_t count, loff_t *ppos)
+{
+   struct rc_client *client = file-private_data;
+   struct rc_dev *dev = client-dev;
+   ssize_t ret;
+   DEFINE_IR_RAW_EVENT(event);
+   bool pulse = true;
+   u32 value;
+
+   if (!dev-tx_ir)
+   return -ENOSYS;
+
+   if ((count  sizeof(u32)) || (count % sizeof(u32)))
+   return -EINVAL;
+
+again:
+   if (kfifo_is_full(dev-txfifo)  dev-exist 
+   (file-f_flags  O_NONBLOCK))
+   return -EAGAIN;
+
+   ret = wait_event_interruptible(dev-txwait,
+  !kfifo_is_full(dev-txfifo) ||
+  !dev-exist);
+   if (ret)
+   return ret;
+
+   if (!dev-exist)
+   return -ENODEV;
+
+   for (ret = 0; ret + sizeof(value) = count; ret += sizeof(value)) {
+   if (copy_from_user(value, buffer + ret, sizeof(value)))
+   return -EFAULT;
+
+   event.duration = US_TO_NS(value);
+   event.pulse = pulse;
+   pulse = !pulse;
+
+   if (kfifo_in_spinlocked(dev-txfifo, event, 1, dev-txlock)
+   != 1)
+   break;
+   }
+
+   if (ret == 0)
+   goto again;
+
+   dev-tx_ir(dev);
+   wake_up_interruptible(dev-txwait);
+
+   return ret;
+}
+
+/**
  * rc_poll() - allows userspace to poll rc device files
  * @file:  the struct file corresponding to the previous open()
  * @wait:  used to keep track of processes waiting for poll events
@@ -1573,8 +1638,10 @@ static unsigned int rc_poll(struct file *file, 
poll_table *wait)
struct rc_client *client = file-private_data;
struct rc_dev *dev = client-dev;
 
+   poll_wait(file, dev-txwait, wait);
poll_wait(file, dev-rxwait, wait);
return ((kfifo_is_empty(client-rxfifo) ? 0 : (POLLIN | POLLRDNORM)) |
+   (kfifo_is_full(dev-txfifo) ? 0 : (POLLOUT | POLLWRNORM)) |
(dev-exist ? 0 : (POLLHUP | POLLERR)));
 }
 
@@ -1601,6 +1668,7 @@ static const struct file_operations rc_fops = {
.open   = rc_open,
.release= rc_release,
.read   = rc_read,
+   .write  = rc_write,
.poll   = rc_poll,
.fasync = rc_fasync,
 };
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index 4a5dbcb..1810984 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -87,6 +87,7 @@ struct ir_raw_event {
  * @client_lock: protects client_list
  * @txfifo: fifo with tx data to transmit
  * @txlock: protects txfifo
+ * @txwait: waitqueue for processes waiting to write data to the txfifo
  * @rxwait: waitqueue for processes waiting for data to read
  * @raw: additional data for raw pulse/space devices
  * @input_dev: the input child device used to communicate events to userspace
@@ -141,6 +142,7 @@ struct rc_dev {
spinlock_t  client_lock;
DECLARE_KFIFO_PTR(txfifo, struct ir_raw_event);
spinlock_t  

[PATCH 31/43] rc-core: allow empty keymaps

2012-05-23 Thread David Härdeman
Remove the RC_MAP_EMPTY hack and instead allow for empty keymaps.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/dvb/dvb-usb/af9015.c |4 
 drivers/media/dvb/dvb-usb/af9035.c |1 -
 drivers/media/dvb/dvb-usb/dvb-usb-remote.c |4 +---
 drivers/media/dvb/dvb-usb/rtl28xxu.c   |2 --
 drivers/media/rc/gpio-ir-recv.c|1 -
 drivers/media/rc/rc-keytable.c |   13 -
 drivers/media/rc/rc-loopback.c |1 -
 drivers/media/rc/rc-main.c |   17 +
 drivers/media/video/cx88/cx88-input.c  |6 --
 drivers/media/video/ir-kbd-i2c.c   |4 +---
 drivers/media/video/ivtv/ivtv-i2c.c|2 +-
 include/media/rc-map.h |1 -
 12 files changed, 8 insertions(+), 48 deletions(-)

diff --git a/drivers/media/dvb/dvb-usb/af9015.c 
b/drivers/media/dvb/dvb-usb/af9015.c
index 4733044..b82e235 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -809,10 +809,6 @@ static void af9015_set_remote_config(struct usb_device 
*udev,
}
}
 
-   /* finally load empty just for leaving IR receiver enabled */
-   if (!props-rc.core.rc_codes)
-   props-rc.core.rc_codes = RC_MAP_EMPTY;
-
return;
 }
 
diff --git a/drivers/media/dvb/dvb-usb/af9035.c 
b/drivers/media/dvb/dvb-usb/af9035.c
index 42094e1..62714ad 100644
--- a/drivers/media/dvb/dvb-usb/af9035.c
+++ b/drivers/media/dvb/dvb-usb/af9035.c
@@ -1061,7 +1061,6 @@ static struct dvb_usb_device_properties 
af9035_properties[] = {
.rc_query   = NULL,
.rc_interval= AF9035_POLL,
.allowed_protos = RC_TYPE_UNKNOWN,
-   .rc_codes   = RC_MAP_EMPTY,
},
.num_device_descs = 5,
.devices = {
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c 
b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index 41bacff..909e95c 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -313,10 +313,8 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
 
if (d-props.rc.legacy.rc_map_table  d-props.rc.legacy.rc_query)
d-props.rc.mode = DVB_RC_LEGACY;
-   else if (d-props.rc.core.rc_codes)
-   d-props.rc.mode = DVB_RC_CORE;
else
-   return 0;
+   d-props.rc.mode = DVB_RC_CORE;
 
usb_make_path(d-udev, d-rc_phys, sizeof(d-rc_phys));
strlcat(d-rc_phys, /ir0, sizeof(d-rc_phys));
diff --git a/drivers/media/dvb/dvb-usb/rtl28xxu.c 
b/drivers/media/dvb/dvb-usb/rtl28xxu.c
index 9dbde0a..8d67bc6 100644
--- a/drivers/media/dvb/dvb-usb/rtl28xxu.c
+++ b/drivers/media/dvb/dvb-usb/rtl28xxu.c
@@ -819,7 +819,6 @@ static struct dvb_usb_device_properties 
rtl28xxu_properties[] = {
.rc_query   = rtl2831u_rc_query,
.rc_interval= 400,
.allowed_protos = RC_BIT_NEC,
-   .rc_codes   = RC_MAP_EMPTY,
},
 
.i2c_algo = rtl28xxu_i2c_algo,
@@ -881,7 +880,6 @@ static struct dvb_usb_device_properties 
rtl28xxu_properties[] = {
.rc_query   = rtl2832u_rc_query,
.rc_interval= 400,
.allowed_protos = RC_BIT_NEC,
-   .rc_codes   = RC_MAP_EMPTY,
},
 
.i2c_algo = rtl28xxu_i2c_algo,
diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c
index 478b2e9..3ee7455 100644
--- a/drivers/media/rc/gpio-ir-recv.c
+++ b/drivers/media/rc/gpio-ir-recv.c
@@ -87,7 +87,6 @@ static int __devinit gpio_ir_recv_probe(struct 
platform_device *pdev)
rcdev-input_name = GPIO_IR_DEVICE_NAME;
rcdev-input_id.bustype = BUS_HOST;
rcdev-driver_name = GPIO_IR_DRIVER_NAME;
-   rcdev-map_name = RC_MAP_EMPTY;
 
gpio_dev-rcdev = rcdev;
gpio_dev-gpio_nr = pdata-gpio_nr;
diff --git a/drivers/media/rc/rc-keytable.c b/drivers/media/rc/rc-keytable.c
index d6e68d0..d5b1d88 100644
--- a/drivers/media/rc/rc-keytable.c
+++ b/drivers/media/rc/rc-keytable.c
@@ -54,6 +54,9 @@ struct rc_map *rc_map_get(const char *name)
 
struct rc_map_list *map;
 
+   if (!name)
+   return NULL;
+
map = seek_rc_map(name);
 #ifdef MODULE
if (!map) {
@@ -777,7 +780,6 @@ struct rc_keytable *rc_keytable_create(struct rc_dev *dev,
 {
struct rc_keytable *kt;
struct input_dev *idev = NULL;
-   struct rc_map *rc_map = NULL;
int error;
 
kt = kzalloc(sizeof(*kt), GFP_KERNEL);
@@ -802,14 +804,7 @@ struct rc_keytable *rc_keytable_create(struct rc_dev *dev,
input_set_drvdata(idev, kt);
setup_timer(kt-timer_keyup, rc_timer_keyup, (unsigned long)kt);
 
-   if 

[PATCH 39/43] rc-core: use struct rc_event to signal TX events from userspace

2012-05-23 Thread David Härdeman
Using struct rc_event as the data unit for writes from userspace provides
more flexibility and easier future compatibility with future developments
(e.g. if rc-core grew support for some very different transmission, such
as RF transmission).

Signed-off-by: David Härdeman da...@hardeman.nu
---
 drivers/media/rc/ene_ir.c|   24 ++--
 drivers/media/rc/ene_ir.h|2 -
 drivers/media/rc/ir-lirc-codec.c |   12 +++---
 drivers/media/rc/ite-cir.c   |   19 +
 drivers/media/rc/mceusb.c|   10 +++--
 drivers/media/rc/nuvoton-cir.c   |   10 +++--
 drivers/media/rc/rc-loopback.c   |   10 -
 drivers/media/rc/rc-main.c   |   18 +++--
 drivers/media/rc/redrat3.c   |   20 --
 drivers/media/rc/winbond-cir.c   |   22 +--
 include/media/rc-core.h  |   79 +++---
 include/media/rc-ir-raw.h|6 +++
 12 files changed, 133 insertions(+), 99 deletions(-)

diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c
index 2c2cfd5..9669311 100644
--- a/drivers/media/rc/ene_ir.c
+++ b/drivers/media/rc/ene_ir.c
@@ -604,7 +604,7 @@ static void ene_tx_enable(struct ene_device *dev)
 static void ene_tx_disable(struct ene_device *dev)
 {
ene_write_reg(dev, ENE_CIRCFG, dev-saved_conf1);
-   init_ir_raw_event(dev-tx_event);
+   dev-tx_event.val = 0;
 }
 
 
@@ -614,7 +614,7 @@ static void ene_tx_sample(struct ene_device *dev)
u8 raw_tx;
 
/* Grab next TX sample */
-   if (!dev-tx_event.duration) {
+   while (!dev-tx_event.val) {
 
if (!kfifo_get(dev-rdev-txfifo, dev-tx_event)) {
if (!dev-tx_done) {
@@ -629,19 +629,21 @@ static void ene_tx_sample(struct ene_device *dev)
}
}
 
-   dev-tx_event.duration = 
DIV_ROUND_CLOSEST(dev-tx_event.duration,
-  
US_TO_NS(sample_period));
-   if (!dev-tx_event.duration)
-   dev-tx_event.duration = 1;
+   if (!is_ir_raw_timing_event(dev-tx_event))
+   continue;
+
+   dev-tx_event.val = max_t(u64, 1,
+ DIV_ROUND_CLOSEST(dev-tx_event.val,
+   
US_TO_NS(sample_period)));
}
 
-   raw_tx = min_t(unsigned, dev-tx_event.duration, ENE_CIRRLC_OUT_MASK);
-   dev-tx_event.duration -= raw_tx;
+   raw_tx = min_t(unsigned, dev-tx_event.val, ENE_CIRRLC_OUT_MASK);
+   dev-tx_event.val -= raw_tx;
 
dbg(TX: sample %8d (%s), raw_tx * sample_period,
-   dev-tx_event.pulse ? pulse : space);
+   dev-tx_event.code == RC_IR_RAW_PULSE ? pulse : space);
 
-   if (dev-tx_event.pulse)
+   if (dev-tx_event.code == RC_IR_RAW_PULSE)
raw_tx |= ENE_CIRRLC_OUT_PULSE;
 
ene_write_reg(dev,
@@ -953,7 +955,7 @@ static int ene_transmit(struct rc_dev *rdev)
dev-tx_reg = 0;
dev-tx_done = false;
 
-   init_ir_raw_event(dev-tx_event);
+   dev-tx_event.val = 0;
dbg(TX: %d samples, kfifo_len(rdev-txfifo));
 
spin_lock_irqsave(dev-hw_lock, flags);
diff --git a/drivers/media/rc/ene_ir.h b/drivers/media/rc/ene_ir.h
index 975d67a..d0898e1 100644
--- a/drivers/media/rc/ene_ir.h
+++ b/drivers/media/rc/ene_ir.h
@@ -224,7 +224,7 @@ struct ene_device {
u8  saved_conf1;/* saved FEC0 reg */
 
/* TX buffer */
-   struct ir_raw_event tx_event;   /* current sample for TX */
+   struct rc_event tx_event;   /* current sample for TX */
bool tx_done;   /* done transmitting */
struct completion tx_complete;  /* TX completion */
struct timer_list tx_sim_timer;
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
index 6811db9..a5b0368 100644
--- a/drivers/media/rc/ir-lirc-codec.c
+++ b/drivers/media/rc/ir-lirc-codec.c
@@ -109,8 +109,8 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const 
char __user *buf,
ssize_t ret;
s64 towait;
unsigned int duration = 0; /* signal duration in us */
-   DEFINE_IR_RAW_EVENT(event);
bool pulse = true;
+   struct rc_event ev;
 
if (!lirc || !lirc-dev)
return -EFAULT;
@@ -122,14 +122,16 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, 
const char __user *buf,
if (n % sizeof(u32) || ((n / sizeof(u32)) % 2) == 0)
return -EINVAL;
 
+   ev.type = RC_IR_RAW;
+   ev.reserved = 0x0;
+
for (ret = 0; ret + sizeof(u32) = n; ret += sizeof(u32)) {
if (copy_from_user(value, buf + ret, sizeof(u32)))
return -EFAULT;
 
-   event.pulse = pulse;
-   event.duration = US_TO_NS(value);
-   if 

[PATCH 43/43] rc-core: make rc-core.h userspace friendly

2012-05-23 Thread David Härdeman
A few ifdef __KERNEL__ and some reorganisation to make rc-core.h usable from
userspace programs.

Signed-off-by: David Härdeman da...@hardeman.nu
---
 include/media/rc-core.h |   76 +--
 1 file changed, 54 insertions(+), 22 deletions(-)

diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index e311242..0685a4c 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -16,20 +16,21 @@
 #ifndef _RC_CORE
 #define _RC_CORE
 
+#ifdef __KERNEL__
 #include linux/spinlock.h
 #include linux/kfifo.h
 #include linux/time.h
 #include linux/timer.h
 #include media/rc-map.h
+#else
+#include sys/time.h
+#include sys/ioctl.h
+#include sys/types.h
+#include linux/types.h
+#endif
 
-extern int rc_core_debug;
-#define IR_dprintk(level, fmt, ...)\
-do {   \
-   if (rc_core_debug = level) \
-   pr_debug(%s:  fmt, __func__, ##__VA_ARGS__);  \
-} while (0)
-
-#define RC_VERSION 0x01
+#define RC_VERSION 0x01
+#define RC_MAX_KEYTABLES   32
 
 /*
  * ioctl definitions
@@ -176,18 +177,37 @@ struct rc_keytable_ioctl {
char name[RC_KEYTABLE_NAME_SIZE];
 } __packed;
 
+/**
+ * enum rc_driver_type - describe the kind of driver/hardware used
+ * @RC_DRIVER_SCANCODE:generates scancodes
+ * @RC_DRIVER_IR_RAW:  generates IR timings which need to be decoded
+ */
 enum rc_driver_type {
-   RC_DRIVER_SCANCODE = 0, /* Driver or hardware generates a scancode */
-   RC_DRIVER_IR_RAW,   /* Needs a Infra-Red pulse/space decoder */
+   RC_DRIVER_SCANCODE = 0,
+   RC_DRIVER_IR_RAW,
 };
 
-/* This is used for the input EVIOC[SG]KEYCODE_V2 ioctls */
+/**
+ * struct rc_scancode - protocol/scancode pair
+ * @protocol:  the protocol of the rc command
+ * @reserved:  for future use and padding, set to zero
+ * @scancode:  the scancode of the command
+ */
 struct rc_scancode {
__u16 protocol;
__u16 reserved[3];
__u64 scancode;
 };
 
+/**
+ * struct rc_keymap_entry - used in EVIOC[SG]KEYCODE_V2 ioctls
+ * @flags: see struct input_keymap_entry
+ * @len:   see struct input_keymap_entry
+ * @index: see struct input_keymap_entry
+ * @keycode:   see struct input_keymap_entry
+ * @rc:the scancode/protocol definition, see struct 
rc_scancode
+ * @raw:   alternative representation of @rc
+ */
 struct rc_keymap_entry {
__u8  flags;
__u8  len;
@@ -203,7 +223,7 @@ struct rc_keymap_entry {
  * struct rc_event - used to communicate rc events to userspace
  * @type:  the event type
  * @code:  the event code (type specific)
- * @reserved:  zero for now
+ * @reserved:  padding, zero for now
  * @val:   the event value (type and code specific)
  */
 struct rc_event {
@@ -239,6 +259,9 @@ struct rc_event {
 #define RC_IR_RAW_CARRIER  0x5
 #define RC_IR_RAW_DUTY_CYCLE   0x6
 
+#ifdef __KERNEL__
+/* The rest is implementational details which shouldn't concern userspace */
+
 /**
  * struct rc_dev - represents a remote control device
  * @dev: driver model's view of this device
@@ -300,7 +323,6 @@ struct rc_event {
  * @get_ir_tx: allow driver to provide tx settings
  * @set_ir_tx: allow driver to change tx settings
  */
-#define RC_MAX_KEYTABLES   32
 #define RC_TX_KFIFO_SIZE   1024
 struct rc_dev {
struct device   dev;
@@ -350,22 +372,16 @@ struct rc_dev {
void(*get_ir_tx)(struct rc_dev *dev, struct 
rc_ir_tx *tx);
int (*set_ir_tx)(struct rc_dev *dev, struct 
rc_ir_tx *tx);
 };
-
 #define to_rc_dev(d) container_of(d, struct rc_dev, dev)
 
-/*
- * From rc-main.c
- * Those functions can be used on any type of Remote Controller. They
- * basically creates an input_dev and properly reports the device as a
- * Remote Controller, at sys/class/rc.
- */
-
+/* From rc-main.c - see inline kerneldoc */
 struct rc_dev *rc_allocate_device(void);
 void rc_free_device(struct rc_dev *dev);
 int rc_register_device(struct rc_dev *dev);
 void rc_unregister_device(struct rc_dev *dev);
 void rc_event(struct rc_dev *dev, u16 type, u16 code, u64 val);
 
+/* From rc-keytable.c - see inline kerneldoc */
 void rc_repeat(struct rc_dev *dev);
 void rc_keyup(struct rc_dev *dev);
 void rc_do_keydown(struct rc_dev *dev, enum rc_type protocol, u64 scancode, u8 
toggle, bool autoup);
@@ -373,7 +389,22 @@ void rc_do_keydown(struct rc_dev *dev, enum rc_type 
protocol, u64 scancode, u8 t
 #define rc_keydown_notimeout(dev, proto, scan, toggle) rc_do_keydown(dev, 
proto, scan, toggle, false)
 u32 rc_g_keycode_from_table(struct rc_dev *dev, enum rc_type protocol, u64 
scancode);
 
-/* extract mask bits out of data and pack them into the result */
+extern int rc_core_debug;
+#define IR_dprintk(level, fmt, ...)\
+do { 

Re: [PATCH 1/1] as3645a: Remove set_power() from platform data

2012-05-23 Thread Laurent Pinchart
Hi Sakari,

Thanks for the patch.

On Wednesday 16 May 2012 06:12:49 Sakari Ailus wrote:
 The chip is typically powered constantly and no board uses the set_power()
 callback. Remove it.
 
 Signed-off-by: Sakari Ailus sakari.ai...@iki.fi
 ---
  drivers/media/video/as3645a.c |   39 +
  include/media/as3645a.h   |1 -
  2 files changed, 9 insertions(+), 31 deletions(-)
 
 diff --git a/drivers/media/video/as3645a.c b/drivers/media/video/as3645a.c
 index c4b0357..7454660 100644
 --- a/drivers/media/video/as3645a.c
 +++ b/drivers/media/video/as3645a.c
 @@ -512,31 +512,6 @@ static int as3645a_setup(struct as3645a *flash)
   return ret  ~AS_FAULT_INFO_LED_AMOUNT ? -EIO : 0;
  }
 
 -static int __as3645a_set_power(struct as3645a *flash, int on)
 -{
 - int ret;
 -
 - if (!on)
 - as3645a_set_control(flash, AS_MODE_EXT_TORCH, false);
 -
 - if (flash-pdata-set_power) {
 - ret = flash-pdata-set_power(flash-subdev, on);
 - if (ret  0)
 - return ret;
 - }
 -
 - if (!on)
 - return 0;
 -
 - ret = as3645a_setup(flash);
 - if (ret  0) {
 - if (flash-pdata-set_power)
 - flash-pdata-set_power(flash-subdev, 0);
 - }
 -
 - return ret;
 -}
 -
  static int as3645a_set_power(struct v4l2_subdev *sd, int on)
  {
   struct as3645a *flash = to_as3645a(sd);
 @@ -545,9 +520,13 @@ static int as3645a_set_power(struct v4l2_subdev *sd,
 int on) mutex_lock(flash-power_lock);
 
   if (flash-power_count == !on) {
 - ret = __as3645a_set_power(flash, !!on);
 - if (ret  0)
 - goto done;
 + if (!on) {
 + as3645a_set_control(flash, AS_MODE_EXT_TORCH, false);
 + } else {
 + ret = as3645a_setup(flash);
 + if (ret  0)
 + goto done;
 + }
   }
 

If the chip is powered on constantly, why do we need a .s_power() subdev 
operation at all ?

   flash-power_count += on ? 1 : -1;
 @@ -675,7 +654,7 @@ static int as3645a_suspend(struct device *dev)
   if (flash-power_count == 0)
   return 0;
 
 - rval = __as3645a_set_power(flash, 0);
 + rval = as3645a_set_control(flash, AS_MODE_EXT_TORCH, false);
 
   dev_dbg(client-dev, Suspend %s\n, rval  0 ? failed : ok);
 
 @@ -692,7 +671,7 @@ static int as3645a_resume(struct device *dev)
   if (flash-power_count == 0)
   return 0;
 
 - rval = __as3645a_set_power(flash, 1);
 + rval = as3645a_setup(flash);
 
   dev_dbg(client-dev, Resume %s\n, rval  0 ? fail : ok);
 
 diff --git a/include/media/as3645a.h b/include/media/as3645a.h
 index 5075496..a83ab3a 100644
 --- a/include/media/as3645a.h
 +++ b/include/media/as3645a.h
 @@ -57,7 +57,6 @@
   * @timeout_max: Max flash timeout (us, = AS3645A_FLASH_TIMEOUT_MAX)
   */
  struct as3645a_platform_data {
 - int (*set_power)(struct v4l2_subdev *subdev, int on);
   unsigned int vref;
   unsigned int peak;
   bool ext_strobe;

-- 
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 1/1] as3645a: Remove set_power() from platform data

2012-05-23 Thread Sakari Ailus
Hi Laurent,

On Wed, May 23, 2012 at 01:00:08PM +0200, Laurent Pinchart wrote:
 Hi Sakari,
 
 Thanks for the patch.
 
 On Wednesday 16 May 2012 06:12:49 Sakari Ailus wrote:
  The chip is typically powered constantly and no board uses the set_power()
  callback. Remove it.
  
  Signed-off-by: Sakari Ailus sakari.ai...@iki.fi
  ---
   drivers/media/video/as3645a.c |   39 +
   include/media/as3645a.h   |1 -
   2 files changed, 9 insertions(+), 31 deletions(-)
  
  diff --git a/drivers/media/video/as3645a.c b/drivers/media/video/as3645a.c
  index c4b0357..7454660 100644
  --- a/drivers/media/video/as3645a.c
  +++ b/drivers/media/video/as3645a.c
  @@ -512,31 +512,6 @@ static int as3645a_setup(struct as3645a *flash)
  return ret  ~AS_FAULT_INFO_LED_AMOUNT ? -EIO : 0;
   }
  
  -static int __as3645a_set_power(struct as3645a *flash, int on)
  -{
  -   int ret;
  -
  -   if (!on)
  -   as3645a_set_control(flash, AS_MODE_EXT_TORCH, false);
  -
  -   if (flash-pdata-set_power) {
  -   ret = flash-pdata-set_power(flash-subdev, on);
  -   if (ret  0)
  -   return ret;
  -   }
  -
  -   if (!on)
  -   return 0;
  -
  -   ret = as3645a_setup(flash);
  -   if (ret  0) {
  -   if (flash-pdata-set_power)
  -   flash-pdata-set_power(flash-subdev, 0);
  -   }
  -
  -   return ret;
  -}
  -
   static int as3645a_set_power(struct v4l2_subdev *sd, int on)
   {
  struct as3645a *flash = to_as3645a(sd);
  @@ -545,9 +520,13 @@ static int as3645a_set_power(struct v4l2_subdev *sd,
  int on) mutex_lock(flash-power_lock);
  
  if (flash-power_count == !on) {
  -   ret = __as3645a_set_power(flash, !!on);
  -   if (ret  0)
  -   goto done;
  +   if (!on) {
  +   as3645a_set_control(flash, AS_MODE_EXT_TORCH, false);
  +   } else {
  +   ret = as3645a_setup(flash);
  +   if (ret  0)
  +   goto done;
  +   }
  }
  
 
 If the chip is powered on constantly, why do we need a .s_power() subdev 
 operation at all ?

I don't know why was it there in the first place. Probably to make it easier
to use the driver on boards that required e.g. a regulator for the chip.

But typically they're connected to battery directly. The idle power
consumption is just some tens of µA.

Cheers,

-- 
Sakari Ailus
e-mail: sakari.ai...@iki.fi jabber/XMPP/Gmail: sai...@retiisi.org.uk
--
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 1/1] as3645a: Remove set_power() from platform data

2012-05-23 Thread Laurent Pinchart
Hi Sakari,

On Wednesday 23 May 2012 14:19:51 Sakari Ailus wrote:
 On Wed, May 23, 2012 at 01:00:08PM +0200, Laurent Pinchart wrote:
  On Wednesday 16 May 2012 06:12:49 Sakari Ailus wrote:
   The chip is typically powered constantly and no board uses the
   set_power() callback. Remove it.
   
   Signed-off-by: Sakari Ailus sakari.ai...@iki.fi
   ---
   
drivers/media/video/as3645a.c |   39
+
include/media/as3645a.h   |1 -
2 files changed, 9 insertions(+), 31 deletions(-)
   
   diff --git a/drivers/media/video/as3645a.c
   b/drivers/media/video/as3645a.c
   index c4b0357..7454660 100644
   --- a/drivers/media/video/as3645a.c
   +++ b/drivers/media/video/as3645a.c
   @@ -512,31 +512,6 @@ static int as3645a_setup(struct as3645a *flash)
   
 return ret  ~AS_FAULT_INFO_LED_AMOUNT ? -EIO : 0;

}
   
   -static int __as3645a_set_power(struct as3645a *flash, int on)
   -{
   - int ret;
   -
   - if (!on)
   - as3645a_set_control(flash, AS_MODE_EXT_TORCH, false);
   -
   - if (flash-pdata-set_power) {
   - ret = flash-pdata-set_power(flash-subdev, on);
   - if (ret  0)
   - return ret;
   - }
   -
   - if (!on)
   - return 0;
   -
   - ret = as3645a_setup(flash);
   - if (ret  0) {
   - if (flash-pdata-set_power)
   - flash-pdata-set_power(flash-subdev, 0);
   - }
   -
   - return ret;
   -}
   -
   
static int as3645a_set_power(struct v4l2_subdev *sd, int on)
{

 struct as3645a *flash = to_as3645a(sd);
   
   @@ -545,9 +520,13 @@ static int as3645a_set_power(struct v4l2_subdev
   *sd,
   int on) mutex_lock(flash-power_lock);
   
 if (flash-power_count == !on) {
   
   - ret = __as3645a_set_power(flash, !!on);
   - if (ret  0)
   - goto done;
   + if (!on) {
   + as3645a_set_control(flash, AS_MODE_EXT_TORCH, false);
   + } else {
   + ret = as3645a_setup(flash);
   + if (ret  0)
   + goto done;
   + }
   
 }
  
  If the chip is powered on constantly, why do we need a .s_power() subdev
  operation at all ?
 
 I don't know why was it there in the first place. Probably to make it easier
 to use the driver on boards that required e.g. a regulator for the chip.
 
 But typically they're connected to battery directly. The idle power
 consumption is just some tens of µA.

What about on the N9 ?

-- 
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 1/1] as3645a: Remove set_power() from platform data

2012-05-23 Thread Sakari Ailus
On Wed, May 23, 2012 at 01:31:26PM +0200, Laurent Pinchart wrote:
 Hi Sakari,
...
   If the chip is powered on constantly, why do we need a .s_power() subdev
   operation at all ?
  
  I don't know why was it there in the first place. Probably to make it easier
  to use the driver on boards that required e.g. a regulator for the chip.
  
  But typically they're connected to battery directly. The idle power
  consumption is just some tens of µA.
 
 What about on the N9 ?

That function pointer is NULL for N9. I used to configure the GPIOs but that
was wrong in the first place.

-- 
Sakari Ailus
e-mail: sakari.ai...@iki.fi jabber/XMPP/Gmail: sai...@retiisi.org.uk
--
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


[PATCHv6 00/13] Integration of videobuf2 with dmabuf

2012-05-23 Thread Tomasz Stanislawski
Hello everyone,
This patchset adds support for DMABUF [2] importing to V4L2 stack.
The support for DMABUF exporting was moved to separate patchset
due to dependency on patches for DMA mapping redesign by
Marek Szyprowski [4].

v6:
- fixed missing entry in v4l2_memory_names
- fixed a bug occuring after get_user_pages failure
- fixed a bug caused by using invalid vma for get_user_pages
- prepare/finish no longer call dma_sync for dmabuf buffers

v5:
- removed change of importer/exporter behaviour
- fixes vb2_dc_pages_to_sgt basing on Laurent's hints
- changed pin/unpin words to lock/unlock in Doc

v4:
- rebased on mainline 3.4-rc2
- included missing importing support for s5p-fimc and s5p-tv
- added patch for changing map/unmap for importers
- fixes to Documentation part
- coding style fixes
- pairing {map/unmap}_dmabuf in vb2-core
- fixing variable types and semantic of arguments in videobufb2-dma-contig.c

v3:
- rebased on mainline 3.4-rc1
- split 'code refactor' patch to multiple smaller patches
- squashed fixes to Sumit's patches
- patchset is no longer dependant on 'DMA mapping redesign'
- separated path for handling IO and non-IO mappings
- add documentation for DMABUF importing to V4L
- removed all DMABUF exporter related code
- removed usage of dma_get_pages extension

v2:
- extended VIDIOC_EXPBUF argument from integer memoffset to struct
  v4l2_exportbuffer
- added patch that breaks DMABUF spec on (un)map_atachment callcacks but allows
  to work with existing implementation of DMABUF prime in DRM
- all dma-contig code refactoring patches were squashed
- bugfixes

v1: List of changes since [1].
- support for DMA api extension dma_get_pages, the function is used to retrieve
  pages used to create DMA mapping.
- small fixes/code cleanup to videobuf2
- added prepare and finish callbacks to vb2 allocators, it is used keep
  consistency between dma-cpu acess to the memory (by Marek Szyprowski)
- support for exporting of DMABUF buffer in V4L2 and Videobuf2, originated from
  [3].
- support for dma-buf exporting in vb2-dma-contig allocator
- support for DMABUF for s5p-tv and s5p-fimc (capture interface) drivers,
  originated from [3]
- changed handling for userptr buffers (by Marek Szyprowski, Andrzej
  Pietrasiewicz)
- let mmap method to use dma_mmap_writecombine call (by Marek Szyprowski)

[1] 
http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/42966/focus=42968
[2] https://lkml.org/lkml/2011/12/26/29
[3] 
http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/36354/focus=36355
[4] http://thread.gmane.org/gmane.linux.kernel.cross-arch/12819

Laurent Pinchart (2):
  v4l: vb2-dma-contig: Shorten vb2_dma_contig prefix to vb2_dc
  v4l: vb2-dma-contig: Reorder functions

Marek Szyprowski (2):
  v4l: vb2: add prepare/finish callbacks to allocators
  v4l: vb2-dma-contig: add prepare/finish to dma-contig allocator

Sumit Semwal (4):
  v4l: Add DMABUF as a memory type
  v4l: vb2: add support for shared buffer (dma_buf)
  v4l: vb: remove warnings about MEMORY_DMABUF
  v4l: vb2-dma-contig: add support for dma_buf importing

Tomasz Stanislawski (5):
  Documentation: media: description of DMABUF importing in V4L2
  v4l: vb2-dma-contig: Remove unneeded allocation context structure
  v4l: vb2-dma-contig: add support for scatterlist in userptr mode
  v4l: s5p-tv: mixer: support for dmabuf importing
  v4l: s5p-fimc: support for dmabuf importing

 Documentation/DocBook/media/v4l/compat.xml |4 +
 Documentation/DocBook/media/v4l/io.xml |  179 +++
 .../DocBook/media/v4l/vidioc-create-bufs.xml   |1 +
 Documentation/DocBook/media/v4l/vidioc-qbuf.xml|   15 +
 Documentation/DocBook/media/v4l/vidioc-reqbufs.xml |   45 +-
 drivers/media/video/s5p-fimc/Kconfig   |1 +
 drivers/media/video/s5p-fimc/fimc-capture.c|2 +-
 drivers/media/video/s5p-tv/Kconfig |1 +
 drivers/media/video/s5p-tv/mixer_video.c   |2 +-
 drivers/media/video/v4l2-ioctl.c   |1 +
 drivers/media/video/videobuf-core.c|4 +
 drivers/media/video/videobuf2-core.c   |  207 +++-
 drivers/media/video/videobuf2-dma-contig.c |  520 +---
 include/linux/videodev2.h  |7 +
 include/media/videobuf2-core.h |   34 ++
 15 files changed, 924 insertions(+), 99 deletions(-)

-- 
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


[PATCHv6 05/13] v4l: vb2-dma-contig: Shorten vb2_dma_contig prefix to vb2_dc

2012-05-23 Thread Tomasz Stanislawski
From: Laurent Pinchart laurent.pinch...@ideasonboard.com

Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/videobuf2-dma-contig.c |   36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 4b71326..a05784f 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -32,9 +32,9 @@ struct vb2_dc_buf {
struct vb2_vmarea_handler   handler;
 };
 
-static void vb2_dma_contig_put(void *buf_priv);
+static void vb2_dc_put(void *buf_priv);
 
-static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size)
+static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
struct vb2_dc_conf *conf = alloc_ctx;
struct vb2_dc_buf *buf;
@@ -56,7 +56,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned 
long size)
buf-size = size;
 
buf-handler.refcount = buf-refcount;
-   buf-handler.put = vb2_dma_contig_put;
+   buf-handler.put = vb2_dc_put;
buf-handler.arg = buf;
 
atomic_inc(buf-refcount);
@@ -64,7 +64,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned 
long size)
return buf;
 }
 
-static void vb2_dma_contig_put(void *buf_priv)
+static void vb2_dc_put(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
@@ -75,14 +75,14 @@ static void vb2_dma_contig_put(void *buf_priv)
}
 }
 
-static void *vb2_dma_contig_cookie(void *buf_priv)
+static void *vb2_dc_cookie(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
return buf-dma_addr;
 }
 
-static void *vb2_dma_contig_vaddr(void *buf_priv)
+static void *vb2_dc_vaddr(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
if (!buf)
@@ -91,14 +91,14 @@ static void *vb2_dma_contig_vaddr(void *buf_priv)
return buf-vaddr;
 }
 
-static unsigned int vb2_dma_contig_num_users(void *buf_priv)
+static unsigned int vb2_dc_num_users(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
return atomic_read(buf-refcount);
 }
 
-static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma)
+static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
 
@@ -111,7 +111,7 @@ static int vb2_dma_contig_mmap(void *buf_priv, struct 
vm_area_struct *vma)
  vb2_common_vm_ops, buf-handler);
 }
 
-static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr,
+static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write)
 {
struct vb2_dc_buf *buf;
@@ -138,7 +138,7 @@ static void *vb2_dma_contig_get_userptr(void *alloc_ctx, 
unsigned long vaddr,
return buf;
 }
 
-static void vb2_dma_contig_put_userptr(void *mem_priv)
+static void vb2_dc_put_userptr(void *mem_priv)
 {
struct vb2_dc_buf *buf = mem_priv;
 
@@ -150,14 +150,14 @@ static void vb2_dma_contig_put_userptr(void *mem_priv)
 }
 
 const struct vb2_mem_ops vb2_dma_contig_memops = {
-   .alloc  = vb2_dma_contig_alloc,
-   .put= vb2_dma_contig_put,
-   .cookie = vb2_dma_contig_cookie,
-   .vaddr  = vb2_dma_contig_vaddr,
-   .mmap   = vb2_dma_contig_mmap,
-   .get_userptr= vb2_dma_contig_get_userptr,
-   .put_userptr= vb2_dma_contig_put_userptr,
-   .num_users  = vb2_dma_contig_num_users,
+   .alloc  = vb2_dc_alloc,
+   .put= vb2_dc_put,
+   .cookie = vb2_dc_cookie,
+   .vaddr  = vb2_dc_vaddr,
+   .mmap   = vb2_dc_mmap,
+   .get_userptr= vb2_dc_get_userptr,
+   .put_userptr= vb2_dc_put_userptr,
+   .num_users  = vb2_dc_num_users,
 };
 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
 
-- 
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


[PATCHv6 06/13] v4l: vb2-dma-contig: Remove unneeded allocation context structure

2012-05-23 Thread Tomasz Stanislawski
vb2-dma-contig returns a vb2_dc_conf structure instance as the vb2
allocation context. That structure only stores a pointer to the physical
device. Remove it and use the device pointer directly as the allocation
context.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/videobuf2-dma-contig.c |   29 +++-
 1 file changed, 7 insertions(+), 22 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index a05784f..a019cd1 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -18,12 +18,8 @@
 #include media/videobuf2-dma-contig.h
 #include media/videobuf2-memops.h
 
-struct vb2_dc_conf {
-   struct device   *dev;
-};
-
 struct vb2_dc_buf {
-   struct vb2_dc_conf  *conf;
+   struct device   *dev;
void*vaddr;
dma_addr_t  dma_addr;
unsigned long   size;
@@ -36,23 +32,21 @@ static void vb2_dc_put(void *buf_priv);
 
 static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
-   struct vb2_dc_conf *conf = alloc_ctx;
+   struct device *dev = alloc_ctx;
struct vb2_dc_buf *buf;
 
buf = kzalloc(sizeof *buf, GFP_KERNEL);
if (!buf)
return ERR_PTR(-ENOMEM);
 
-   buf-vaddr = dma_alloc_coherent(conf-dev, size, buf-dma_addr,
-   GFP_KERNEL);
+   buf-vaddr = dma_alloc_coherent(dev, size, buf-dma_addr, GFP_KERNEL);
if (!buf-vaddr) {
-   dev_err(conf-dev, dma_alloc_coherent of size %ld failed\n,
-   size);
+   dev_err(dev, dma_alloc_coherent of size %ld failed\n, size);
kfree(buf);
return ERR_PTR(-ENOMEM);
}
 
-   buf-conf = conf;
+   buf-dev = dev;
buf-size = size;
 
buf-handler.refcount = buf-refcount;
@@ -69,7 +63,7 @@ static void vb2_dc_put(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
 
if (atomic_dec_and_test(buf-refcount)) {
-   dma_free_coherent(buf-conf-dev, buf-size, buf-vaddr,
+   dma_free_coherent(buf-dev, buf-size, buf-vaddr,
  buf-dma_addr);
kfree(buf);
}
@@ -163,21 +157,12 @@ EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
 
 void *vb2_dma_contig_init_ctx(struct device *dev)
 {
-   struct vb2_dc_conf *conf;
-
-   conf = kzalloc(sizeof *conf, GFP_KERNEL);
-   if (!conf)
-   return ERR_PTR(-ENOMEM);
-
-   conf-dev = dev;
-
-   return conf;
+   return dev;
 }
 EXPORT_SYMBOL_GPL(vb2_dma_contig_init_ctx);
 
 void vb2_dma_contig_cleanup_ctx(void *alloc_ctx)
 {
-   kfree(alloc_ctx);
 }
 EXPORT_SYMBOL_GPL(vb2_dma_contig_cleanup_ctx);
 
-- 
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


[PATCHv6 09/13] v4l: vb2: add prepare/finish callbacks to allocators

2012-05-23 Thread Tomasz Stanislawski
From: Marek Szyprowski m.szyprow...@samsung.com

This patch adds support for prepare/finish callbacks in VB2 allocators. These
callback are used for buffer flushing.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/videobuf2-core.c |   11 +++
 include/media/videobuf2-core.h   |7 +++
 2 files changed, 18 insertions(+)

diff --git a/drivers/media/video/videobuf2-core.c 
b/drivers/media/video/videobuf2-core.c
index f43cfa4..d60ed25 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -845,6 +845,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
 {
struct vb2_queue *q = vb-vb2_queue;
unsigned long flags;
+   unsigned int plane;
 
if (vb-state != VB2_BUF_STATE_ACTIVE)
return;
@@ -855,6 +856,10 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
dprintk(4, Done processing on buffer %d, state: %d\n,
vb-v4l2_buf.index, vb-state);
 
+   /* sync buffers */
+   for (plane = 0; plane  vb-num_planes; ++plane)
+   call_memop(q, finish, vb-planes[plane].mem_priv);
+
/* Add the buffer to the done buffers list */
spin_lock_irqsave(q-done_lock, flags);
vb-state = state;
@@ -1137,9 +1142,15 @@ err:
 static void __enqueue_in_driver(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb-vb2_queue;
+   unsigned int plane;
 
vb-state = VB2_BUF_STATE_ACTIVE;
atomic_inc(q-queued_count);
+
+   /* sync buffers */
+   for (plane = 0; plane  vb-num_planes; ++plane)
+   call_memop(q, prepare, vb-planes[plane].mem_priv);
+
q-ops-buf_queue(vb);
 }
 
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 859bbaf..d079f92 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -56,6 +56,10 @@ struct vb2_fileio_data;
  * dmabuf
  * @unmap_dmabuf: releases access control to the dmabuf - allocator is notified
  *   that this driver is done using the dmabuf for now
+ * @prepare:   called everytime the buffer is passed from userspace to the
+ * driver, usefull for cache synchronisation, optional
+ * @finish:called everytime the buffer is passed back from the driver
+ * to the userspace, also optional
  * @vaddr: return a kernel virtual address to a given memory buffer
  * associated with the passed private structure or NULL if no
  * such mapping exists
@@ -82,6 +86,9 @@ struct vb2_mem_ops {
unsigned long size, int write);
void(*put_userptr)(void *buf_priv);
 
+   void(*prepare)(void *buf_priv);
+   void(*finish)(void *buf_priv);
+
void*(*attach_dmabuf)(void *alloc_ctx, struct dma_buf *dbuf,
unsigned long size, int write);
void(*detach_dmabuf)(void *buf_priv);
-- 
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


[PATCHv6 11/13] v4l: vb2-dma-contig: add support for dma_buf importing

2012-05-23 Thread Tomasz Stanislawski
From: Sumit Semwal sumit.sem...@ti.com

This patch makes changes for adding dma-contig as a dma_buf user. It provides
function implementations for the {attach, detach, map, unmap}_dmabuf()
mem_ops of DMABUF memory type.

Signed-off-by: Sumit Semwal sumit.sem...@ti.com
Signed-off-by: Sumit Semwal sumit.sem...@linaro.org
[author of the original patch]
Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
[integration with refactored dma-contig allocator]
Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/videobuf2-dma-contig.c |  119 +++-
 1 file changed, 117 insertions(+), 2 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index bb32e7e..9c213bc 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -10,6 +10,7 @@
  * the Free Software Foundation.
  */
 
+#include linux/dma-buf.h
 #include linux/module.h
 #include linux/scatterlist.h
 #include linux/sched.h
@@ -34,6 +35,9 @@ struct vb2_dc_buf {
 
/* USERPTR related */
struct vm_area_struct   *vma;
+
+   /* DMABUF related */
+   struct dma_buf_attachment   *db_attach;
 };
 
 /*/
@@ -155,7 +159,8 @@ static void vb2_dc_prepare(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
struct sg_table *sgt = buf-dma_sgt;
 
-   if (!sgt)
+   /* DMABUF exporter will flush the cache for us */
+   if (!sgt || buf-db_attach)
return;
 
dma_sync_sg_for_device(buf-dev, sgt-sgl, sgt-nents, buf-dma_dir);
@@ -166,7 +171,8 @@ static void vb2_dc_finish(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
struct sg_table *sgt = buf-dma_sgt;
 
-   if (!sgt)
+   /* DMABUF exporter will flush the cache for us */
+   if (!sgt || buf-db_attach)
return;
 
dma_sync_sg_for_cpu(buf-dev, sgt-sgl, sgt-nents, buf-dma_dir);
@@ -414,6 +420,111 @@ fail_buf:
 }
 
 /*/
+/*   callbacks for DMABUF buffers*/
+/*/
+
+static int vb2_dc_map_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+   struct sg_table *sgt;
+   unsigned long contig_size;
+
+   if (WARN_ON(!buf-db_attach)) {
+   printk(KERN_ERR trying to pin a non attached buffer\n);
+   return -EINVAL;
+   }
+
+   if (WARN_ON(buf-dma_sgt)) {
+   printk(KERN_ERR dmabuf buffer is already pinned\n);
+   return 0;
+   }
+
+   /* get the associated scatterlist for this buffer */
+   sgt = dma_buf_map_attachment(buf-db_attach, buf-dma_dir);
+   if (IS_ERR_OR_NULL(sgt)) {
+   printk(KERN_ERR Error getting dmabuf scatterlist\n);
+   return -EINVAL;
+   }
+
+   /* checking if dmabuf is big enough to store contiguous chunk */
+   contig_size = vb2_dc_get_contiguous_size(sgt);
+   if (contig_size  buf-size) {
+   printk(KERN_ERR contiguous chunk is too small %lu/%lu b\n,
+   contig_size, buf-size);
+   dma_buf_unmap_attachment(buf-db_attach, sgt, buf-dma_dir);
+   return -EFAULT;
+   }
+
+   buf-dma_addr = sg_dma_address(sgt-sgl);
+   buf-dma_sgt = sgt;
+
+   return 0;
+}
+
+static void vb2_dc_unmap_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+   struct sg_table *sgt = buf-dma_sgt;
+
+   if (WARN_ON(!buf-db_attach)) {
+   printk(KERN_ERR trying to unpin a not attached buffer\n);
+   return;
+   }
+
+   if (WARN_ON(!sgt)) {
+   printk(KERN_ERR dmabuf buffer is already unpinned\n);
+   return;
+   }
+
+   dma_buf_unmap_attachment(buf-db_attach, sgt, buf-dma_dir);
+
+   buf-dma_addr = 0;
+   buf-dma_sgt = NULL;
+}
+
+static void vb2_dc_detach_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+
+   /* if vb2 works correctly you should never detach mapped buffer */
+   if (WARN_ON(buf-dma_addr))
+   vb2_dc_unmap_dmabuf(buf);
+
+   /* detach this attachment */
+   dma_buf_detach(buf-db_attach-dmabuf, buf-db_attach);
+   kfree(buf);
+}
+
+static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
+   unsigned long size, int write)
+{
+   struct vb2_dc_buf *buf;
+   struct dma_buf_attachment *dba;
+
+   if (dbuf-size  size)
+   return ERR_PTR(-EFAULT);
+
+   buf = kzalloc(sizeof *buf, GFP_KERNEL);
+   if (!buf)
+   return ERR_PTR(-ENOMEM);
+
+   buf-dev = alloc_ctx;
+   /* create attachment for the dmabuf with the user device */
+   dba = dma_buf_attach(dbuf, buf-dev);
+   if (IS_ERR(dba)) {
+   printk(KERN_ERR failed to attach dmabuf\n);

[PATCHv6 08/13] v4l: vb2-dma-contig: add support for scatterlist in userptr mode

2012-05-23 Thread Tomasz Stanislawski
This patch introduces usage of dma_map_sg to map memory behind
a userspace pointer to a device as dma-contiguous mapping.

This patch contains some of the code kindly provided by Marek Szyprowski
m.szyprow...@samsung.com and Kamil Debski k.deb...@samsung.com and Andrzej
Pietrasiewicz andrze...@samsung.com. Kind thanks for bug reports from Laurent
Pinchart laurent.pinch...@ideasonboard.com and Seung-Woo Kim
sw0312@samsung.com.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/videobuf2-dma-contig.c |  268 ++--
 1 file changed, 252 insertions(+), 16 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 42c6431..068ec11 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -11,6 +11,8 @@
  */
 
 #include linux/module.h
+#include linux/scatterlist.h
+#include linux/sched.h
 #include linux/slab.h
 #include linux/dma-mapping.h
 
@@ -23,6 +25,8 @@ struct vb2_dc_buf {
void*vaddr;
unsigned long   size;
dma_addr_t  dma_addr;
+   enum dma_data_direction dma_dir;
+   struct sg_table *dma_sgt;
 
/* MMAP related */
struct vb2_vmarea_handler   handler;
@@ -33,6 +37,95 @@ struct vb2_dc_buf {
 };
 
 /*/
+/*scatterlist table functions*/
+/*/
+
+static struct sg_table *vb2_dc_pages_to_sgt(struct page **pages,
+   unsigned int n_pages, unsigned long offset, unsigned long size)
+{
+   struct sg_table *sgt;
+   unsigned int chunks;
+   unsigned int i;
+   unsigned int cur_page;
+   int ret;
+   struct scatterlist *s;
+
+   sgt = kzalloc(sizeof *sgt, GFP_KERNEL);
+   if (!sgt)
+   return ERR_PTR(-ENOMEM);
+
+   /* compute number of chunks */
+   chunks = 1;
+   for (i = 1; i  n_pages; ++i)
+   if (pages[i] != pages[i - 1] + 1)
+   ++chunks;
+
+   ret = sg_alloc_table(sgt, chunks, GFP_KERNEL);
+   if (ret) {
+   kfree(sgt);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   /* merging chunks and putting them into the scatterlist */
+   cur_page = 0;
+   for_each_sg(sgt-sgl, s, sgt-orig_nents, i) {
+   unsigned long chunk_size;
+   unsigned int j;
+
+   for (j = cur_page + 1; j  n_pages; ++j)
+   if (pages[j] != pages[j - 1] + 1)
+   break;
+
+   chunk_size = ((j - cur_page)  PAGE_SHIFT) - offset;
+   sg_set_page(s, pages[cur_page], min(size, chunk_size), offset);
+   size -= chunk_size;
+   offset = 0;
+   cur_page = j;
+   }
+
+   return sgt;
+}
+
+static void vb2_dc_release_sgtable(struct sg_table *sgt)
+{
+   sg_free_table(sgt);
+   kfree(sgt);
+}
+
+static void vb2_dc_sgt_foreach_page(struct sg_table *sgt,
+   void (*cb)(struct page *pg))
+{
+   struct scatterlist *s;
+   unsigned int i;
+
+   for_each_sg(sgt-sgl, s, sgt-nents, i) {
+   struct page *page = sg_page(s);
+   unsigned int n_pages = PAGE_ALIGN(s-offset + s-length)
+PAGE_SHIFT;
+   unsigned int j;
+
+   for (j = 0; j  n_pages; ++j, ++page)
+   cb(page);
+   }
+}
+
+static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt)
+{
+   struct scatterlist *s;
+   dma_addr_t expected = sg_dma_address(sgt-sgl);
+   unsigned int i;
+   unsigned long size = 0;
+
+   for_each_sg(sgt-sgl, s, sgt-nents, i) {
+   if (sg_dma_address(s) != expected)
+   break;
+   expected = sg_dma_address(s) + sg_dma_len(s);
+   size += sg_dma_len(s);
+   }
+   return size;
+}
+
+/*/
 /* callbacks for all buffers */
 /*/
 
@@ -117,42 +210,185 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 /*   callbacks for USERPTR buffers   */
 /*/
 
+static inline int vma_is_io(struct vm_area_struct *vma)
+{
+   return !!(vma-vm_flags  (VM_IO | VM_PFNMAP));
+}
+
+static int vb2_dc_get_user_pages(unsigned long start, struct page **pages,
+   int n_pages, struct vm_area_struct *vma, int write)
+{
+   if (vma_is_io(vma)) {
+   unsigned int i;
+
+   for (i = 0; i  n_pages; ++i, start += PAGE_SIZE) {
+   unsigned long pfn;
+   int ret = 

[PATCHv6 07/13] v4l: vb2-dma-contig: Reorder functions

2012-05-23 Thread Tomasz Stanislawski
From: Laurent Pinchart laurent.pinch...@ideasonboard.com

Group functions by buffer type.

Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/videobuf2-dma-contig.c |   92 
 1 file changed, 54 insertions(+), 38 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index a019cd1..42c6431 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -21,14 +21,56 @@
 struct vb2_dc_buf {
struct device   *dev;
void*vaddr;
-   dma_addr_t  dma_addr;
unsigned long   size;
-   struct vm_area_struct   *vma;
-   atomic_trefcount;
+   dma_addr_t  dma_addr;
+
+   /* MMAP related */
struct vb2_vmarea_handler   handler;
+   atomic_trefcount;
+
+   /* USERPTR related */
+   struct vm_area_struct   *vma;
 };
 
-static void vb2_dc_put(void *buf_priv);
+/*/
+/* callbacks for all buffers */
+/*/
+
+static void *vb2_dc_cookie(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return buf-dma_addr;
+}
+
+static void *vb2_dc_vaddr(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return buf-vaddr;
+}
+
+static unsigned int vb2_dc_num_users(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return atomic_read(buf-refcount);
+}
+
+/*/
+/*callbacks for MMAP buffers */
+/*/
+
+static void vb2_dc_put(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   if (!atomic_dec_and_test(buf-refcount))
+   return;
+
+   dma_free_coherent(buf-dev, buf-size, buf-vaddr, buf-dma_addr);
+   kfree(buf);
+}
 
 static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
@@ -58,40 +100,6 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
return buf;
 }
 
-static void vb2_dc_put(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   if (atomic_dec_and_test(buf-refcount)) {
-   dma_free_coherent(buf-dev, buf-size, buf-vaddr,
- buf-dma_addr);
-   kfree(buf);
-   }
-}
-
-static void *vb2_dc_cookie(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   return buf-dma_addr;
-}
-
-static void *vb2_dc_vaddr(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-   if (!buf)
-   return NULL;
-
-   return buf-vaddr;
-}
-
-static unsigned int vb2_dc_num_users(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   return atomic_read(buf-refcount);
-}
-
 static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
@@ -105,6 +113,10 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
  vb2_common_vm_ops, buf-handler);
 }
 
+/*/
+/*   callbacks for USERPTR buffers   */
+/*/
+
 static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write)
 {
@@ -143,6 +155,10 @@ static void vb2_dc_put_userptr(void *mem_priv)
kfree(buf);
 }
 
+/*/
+/*   DMA CONTIG exported functions   */
+/*/
+
 const struct vb2_mem_ops vb2_dma_contig_memops = {
.alloc  = vb2_dc_alloc,
.put= vb2_dc_put,
-- 
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


[PATCHv6 13/13] v4l: s5p-fimc: support for dmabuf importing

2012-05-23 Thread Tomasz Stanislawski
This patch enhances s5p-fimc with support for DMABUF importing via
V4L2_MEMORY_DMABUF memory type.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
Acked-by: Sylwester Nawrocki s.nawro...@samsung.com
---
 drivers/media/video/s5p-fimc/Kconfig|1 +
 drivers/media/video/s5p-fimc/fimc-capture.c |2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/video/s5p-fimc/Kconfig 
b/drivers/media/video/s5p-fimc/Kconfig
index a564f7e..3106026 100644
--- a/drivers/media/video/s5p-fimc/Kconfig
+++ b/drivers/media/video/s5p-fimc/Kconfig
@@ -14,6 +14,7 @@ config VIDEO_S5P_FIMC
depends on I2C
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
+   select DMA_SHARED_BUFFER
help
  This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC camera host
  interface and video postprocessor (FIMC and FIMC-LITE) devices.
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c 
b/drivers/media/video/s5p-fimc/fimc-capture.c
index 3545745..cd27e33 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -1609,7 +1609,7 @@ static int fimc_register_capture_device(struct fimc_dev 
*fimc,
q = fimc-vid_cap.vbq;
memset(q, 0, sizeof(*q));
q-type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-   q-io_modes = VB2_MMAP | VB2_USERPTR;
+   q-io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
q-drv_priv = fimc-vid_cap.ctx;
q-ops = fimc_capture_qops;
q-mem_ops = vb2_dma_contig_memops;
-- 
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


[PATCHv6 03/13] v4l: vb2: add support for shared buffer (dma_buf)

2012-05-23 Thread Tomasz Stanislawski
From: Sumit Semwal sumit.sem...@ti.com

This patch adds support for DMABUF memory type in videobuf2. It calls relevant
APIs of dma_buf for v4l reqbuf / qbuf / dqbuf operations.

For this version, the support is for videobuf2 as a user of the shared buffer;
so the allocation of the buffer is done outside of V4L2. [A sample allocator of
dma-buf shared buffer is given at [1]]

[1]: Rob Clark's DRM:
   https://github.com/robclark/kernel-omap4/commits/drmplane-dmabuf

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
   [original work in the PoC for buffer sharing]
Signed-off-by: Sumit Semwal sumit.sem...@ti.com
Signed-off-by: Sumit Semwal sumit.sem...@linaro.org
Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/videobuf2-core.c |  196 +-
 include/media/videobuf2-core.h   |   27 +
 2 files changed, 219 insertions(+), 4 deletions(-)

diff --git a/drivers/media/video/videobuf2-core.c 
b/drivers/media/video/videobuf2-core.c
index 9d4e9ed..f43cfa4 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -109,6 +109,36 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
 }
 
 /**
+ * __vb2_plane_dmabuf_put() - release memory associated with
+ * a DMABUF shared plane
+ */
+static void __vb2_plane_dmabuf_put(struct vb2_queue *q, struct vb2_plane *p)
+{
+   if (!p-mem_priv)
+   return;
+
+   if (p-dbuf_mapped)
+   call_memop(q, unmap_dmabuf, p-mem_priv);
+
+   call_memop(q, detach_dmabuf, p-mem_priv);
+   dma_buf_put(p-dbuf);
+   memset(p, 0, sizeof *p);
+}
+
+/**
+ * __vb2_buf_dmabuf_put() - release memory associated with
+ * a DMABUF shared buffer
+ */
+static void __vb2_buf_dmabuf_put(struct vb2_buffer *vb)
+{
+   struct vb2_queue *q = vb-vb2_queue;
+   unsigned int plane;
+
+   for (plane = 0; plane  vb-num_planes; ++plane)
+   __vb2_plane_dmabuf_put(q, vb-planes[plane]);
+}
+
+/**
  * __setup_offsets() - setup unique offsets (cookies) for every plane in
  * every buffer on the queue
  */
@@ -230,6 +260,8 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned 
int buffers)
/* Free MMAP buffers or release USERPTR buffers */
if (q-memory == V4L2_MEMORY_MMAP)
__vb2_buf_mem_free(vb);
+   else if (q-memory == V4L2_MEMORY_DMABUF)
+   __vb2_buf_dmabuf_put(vb);
else
__vb2_buf_userptr_put(vb);
}
@@ -352,6 +384,12 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, 
struct v4l2_buffer *b)
 */
memcpy(b-m.planes, vb-v4l2_planes,
b-length * sizeof(struct v4l2_plane));
+
+   if (q-memory == V4L2_MEMORY_DMABUF) {
+   unsigned int plane;
+   for (plane = 0; plane  vb-num_planes; ++plane)
+   b-m.planes[plane].m.fd = 0;
+   }
} else {
/*
 * We use length and offset in v4l2_planes array even for
@@ -363,6 +401,8 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct 
v4l2_buffer *b)
b-m.offset = vb-v4l2_planes[0].m.mem_offset;
else if (q-memory == V4L2_MEMORY_USERPTR)
b-m.userptr = vb-v4l2_planes[0].m.userptr;
+   else if (q-memory == V4L2_MEMORY_DMABUF)
+   b-m.fd = 0;
}
 
/*
@@ -454,6 +494,20 @@ static int __verify_mmap_ops(struct vb2_queue *q)
 }
 
 /**
+ * __verify_dmabuf_ops() - verify that all memory operations required for
+ * DMABUF queue type have been provided
+ */
+static int __verify_dmabuf_ops(struct vb2_queue *q)
+{
+   if (!(q-io_modes  VB2_DMABUF) || !q-mem_ops-attach_dmabuf ||
+   !q-mem_ops-detach_dmabuf  || !q-mem_ops-map_dmabuf ||
+   !q-mem_ops-unmap_dmabuf)
+   return -EINVAL;
+
+   return 0;
+}
+
+/**
  * vb2_reqbufs() - Initiate streaming
  * @q: videobuf2 queue
  * @req:   struct passed from userspace to vidioc_reqbufs handler in driver
@@ -486,8 +540,9 @@ int vb2_reqbufs(struct vb2_queue *q, struct 
v4l2_requestbuffers *req)
return -EBUSY;
}
 
-   if (req-memory != V4L2_MEMORY_MMAP
-req-memory != V4L2_MEMORY_USERPTR) {
+   if (req-memory != V4L2_MEMORY_MMAP 
+   req-memory != V4L2_MEMORY_DMABUF 
+   req-memory != V4L2_MEMORY_USERPTR) {
dprintk(1, reqbufs: unsupported memory type\n);
return -EINVAL;
}
@@ -516,6 +571,11 @@ int vb2_reqbufs(struct vb2_queue *q, struct 
v4l2_requestbuffers *req)
return -EINVAL;
}
 
+   if (req-memory == V4L2_MEMORY_DMABUF  __verify_dmabuf_ops(q)) {
+   dprintk(1, reqbufs: DMABUF for current setup unsupported\n);
+   return 

[PATCHv6 02/13] Documentation: media: description of DMABUF importing in V4L2

2012-05-23 Thread Tomasz Stanislawski
This patch adds description and usage examples for importing
DMABUF file descriptor in V4L2.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
CC: linux-...@vger.kernel.org
---
 Documentation/DocBook/media/v4l/compat.xml |4 +
 Documentation/DocBook/media/v4l/io.xml |  179 
 .../DocBook/media/v4l/vidioc-create-bufs.xml   |1 +
 Documentation/DocBook/media/v4l/vidioc-qbuf.xml|   15 ++
 Documentation/DocBook/media/v4l/vidioc-reqbufs.xml |   45 ++---
 5 files changed, 223 insertions(+), 21 deletions(-)

diff --git a/Documentation/DocBook/media/v4l/compat.xml 
b/Documentation/DocBook/media/v4l/compat.xml
index ea42ef8..07a311f 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2587,6 +2587,10 @@ ioctls./para
  paralink linkend=v4l2-auto-focus-areaconstant
  V4L2_CID_AUTO_FOCUS_AREA/constant/link control./para
 /listitem
+listitem
+ paraImporting DMABUF file descriptors as a new IO method described
+ in xref linkend=dmabuf /./para
+/listitem
   /itemizedlist
 /section
 
diff --git a/Documentation/DocBook/media/v4l/io.xml 
b/Documentation/DocBook/media/v4l/io.xml
index fd6aca2..521f699 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -472,6 +472,162 @@ rest should be evident./para
   /footnote/para
   /section
 
+  section id=dmabuf
+titleStreaming I/O (DMA buffer importing)/title
+
+note
+  titleExperimental/title
+  paraThis is an link linkend=experimental experimental /link
+  interface and may change in the future./para
+/note
+
+paraThe DMABUF framework provides a generic mean for sharing buffers between
+ multiple devices. Device drivers that support DMABUF can export a DMA buffer
+to userspace as a file descriptor (known as the exporter role), import a DMA
+buffer from userspace using a file descriptor previously exported for a
+different or the same device (known as the importer role), or both. This
+section describes the DMABUF importer role API in V4L2./para
+
+paraInput and output devices support the streaming I/O method when the
+constantV4L2_CAP_STREAMING/constant flag in the
+structfieldcapabilities/structfield field of v4l2-capability; returned by
+the VIDIOC-QUERYCAP; ioctl is set. Whether importing DMA buffers through
+DMABUF file descriptors is supported is determined by calling the
+VIDIOC-REQBUFS; ioctl with the memory type set to
+constantV4L2_MEMORY_DMABUF/constant./para
+
+paraThis I/O method is dedicated for sharing DMA buffers between V4L and
+other APIs.  Buffers (planes) are allocated by a driver on behalf of the
+application, and exported to the application as file descriptors using an API
+specific to the allocator driver.  Only those file descriptor are exchanged,
+these files and meta-information are passed in v4l2-buffer; (or in
+v4l2-plane; in the multi-planar API case).  The driver must be switched into
+DMABUF I/O mode by calling the VIDIOC-REQBUFS; with the desired buffer type.
+No buffers (planes) are allocated beforehand, consequently they are not indexed
+and cannot be queried like mapped buffers with the
+constantVIDIOC_QUERYBUF/constant ioctl./para
+
+example
+  titleInitiating streaming I/O with DMABUF file descriptors/title
+
+  programlisting
+v4l2-requestbuffers; reqbuf;
+
+memset (amp;reqbuf, 0, sizeof (reqbuf));
+reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+reqbuf.memory = V4L2_MEMORY_DMABUF;
+
+if (ioctl (fd, VIDIOC-REQBUFS;, amp;reqbuf) == -1) {
+   if (errno == EINVAL)
+   printf (Video capturing or DMABUF streaming is not 
supported\n);
+   else
+   perror (VIDIOC_REQBUFS);
+
+   exit (EXIT_FAILURE);
+}
+  /programlisting
+/example
+
+paraBuffer (plane) file is passed on the fly with the VIDIOC-QBUF;
+ioctl. In case of multiplanar buffers, every plane can be associated with a
+different DMABUF descriptor.Although buffers are commonly cycled, applications
+can pass different DMABUF descriptor at each constantVIDIOC_QBUF/constant
+call./para
+
+example
+  titleQueueing DMABUF using single plane API/title
+
+  programlisting
+int buffer_queue(int v4lfd, int index, int dmafd)
+{
+   v4l2-buffer; buf;
+
+   memset(amp;buf, 0, sizeof buf);
+   buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+   buf.memory = V4L2_MEMORY_DMABUF;
+   buf.index = index;
+   buf.m.fd = dmafd;
+
+   if (ioctl (v4lfd, VIDIOC-QBUF;, amp;buf) == -1) {
+   perror (VIDIOC_QBUF);
+   return -1;
+   }
+
+   return 0;
+}
+  /programlisting
+/example
+
+example
+  titleQueueing DMABUF using multi plane API/title
+
+  programlisting
+int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes)
+{
+   v4l2-buffer; buf;
+   

[PATCHv6 12/13] v4l: s5p-tv: mixer: support for dmabuf importing

2012-05-23 Thread Tomasz Stanislawski
This patch enhances s5p-tv with support for DMABUF importing via
V4L2_MEMORY_DMABUF memory type.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
---
 drivers/media/video/s5p-tv/Kconfig   |1 +
 drivers/media/video/s5p-tv/mixer_video.c |2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/video/s5p-tv/Kconfig 
b/drivers/media/video/s5p-tv/Kconfig
index f248b28..2e80126 100644
--- a/drivers/media/video/s5p-tv/Kconfig
+++ b/drivers/media/video/s5p-tv/Kconfig
@@ -10,6 +10,7 @@ config VIDEO_SAMSUNG_S5P_TV
bool Samsung TV driver for S5P platform (experimental)
depends on PLAT_S5P  PM_RUNTIME
depends on EXPERIMENTAL
+   select DMA_SHARED_BUFFER
default n
---help---
  Say Y here to enable selecting the TV output devices for
diff --git a/drivers/media/video/s5p-tv/mixer_video.c 
b/drivers/media/video/s5p-tv/mixer_video.c
index 33fde2a..cff974a 100644
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ b/drivers/media/video/s5p-tv/mixer_video.c
@@ -1078,7 +1078,7 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device 
*mdev,
 
layer-vb_queue = (struct vb2_queue) {
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
-   .io_modes = VB2_MMAP | VB2_USERPTR,
+   .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF,
.drv_priv = layer,
.buf_struct_size = sizeof(struct mxr_buffer),
.ops = mxr_video_qops,
-- 
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


Re: [PATCH 01/10] string: introduce memweight

2012-05-23 Thread Akinobu Mita
2012/5/23 Jan Kara j...@suse.cz:
 On Sun 20-05-12 22:23:14, Akinobu Mita wrote:
 memweight() is the function that counts the total number of bits set
 in memory area.  The memory area doesn't need to be aligned to
 long-word boundary unlike bitmap_weight().
  Thanks for the patch. I have some comments below.

Thanks for the review.

 @@ -824,3 +825,39 @@ void *memchr_inv(const void *start, int c, size_t bytes)
       return check_bytes8(start, value, bytes % 8);
  }
  EXPORT_SYMBOL(memchr_inv);
 +
 +/**
 + * memweight - count the total number of bits set in memory area
 + * @ptr: pointer to the start of the area
 + * @bytes: the size of the area
 + */
 +size_t memweight(const void *ptr, size_t bytes)
 +{
 +     size_t w = 0;
 +     size_t longs;
 +     union {
 +             const void *ptr;
 +             const unsigned char *b;
 +             unsigned long address;
 +     } bitmap;
  Ugh, this is ugly and mostly unnecessary. Just use const unsigned char
 *bitmap.

 +
 +     for (bitmap.ptr = ptr; bytes  0  bitmap.address % sizeof(long);
 +                     bytes--, bitmap.address++)
 +             w += hweight8(*bitmap.b);
  This can be:
        count = ((unsigned long)bitmap) % sizeof(long);

The count should be the size of unaligned area and it can be greater than
bytes. So

count = min(bytes,
sizeof(long) - ((unsigned long)bitmap) % sizeof(long));

        while (count--) {
                w += hweight(*bitmap);
                bitmap++;
                bytes--;
        }
 +
 +     for (longs = bytes / sizeof(long); longs  0; ) {
 +             size_t bits = min_t(size_t, INT_MAX  ~(BITS_PER_LONG - 1),
 +                                     longs * BITS_PER_LONG);
  I find it highly unlikely that someone would have such a large bitmap
 (256 MB or more on 32-bit). Also the condition as you wrote it can just
 overflow so it won't have the desired effect. Just do
        BUG_ON(longs = ULONG_MAX / BITS_PER_LONG);

The bits argument of bitmap_weight() is int type. So this should be

BUG_ON(longs = INT_MAX / BITS_PER_LONG);

 and remove the loop completely. If someone comes with such a huge bitmap,
 the code can be modified easily (after really closely inspecting whether
 such a huge bitmap is really well justified).

size_t memweight(const void *ptr, size_t bytes)
{
size_t w = 0;
size_t longs;
const unsigned char *bitmap = ptr;

for (; bytes  0  ((unsigned long)bitmap) % sizeof(long);
bytes--, bitmap++)
w += hweight8(*bitmap);

longs = bytes / sizeof(long);
BUG_ON(longs = INT_MAX / BITS_PER_LONG);
w += bitmap_weight((unsigned long *)bitmap, longs * BITS_PER_LONG);
bytes -= longs * sizeof(long);
bitmap += longs * sizeof(long);

for (; bytes  0; bytes--, bitmap++)
w += hweight8(*bitmap);

return w;
}
--
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 01/10] string: introduce memweight

2012-05-23 Thread Jan Kara
On Wed 23-05-12 21:12:18, Akinobu Mita wrote:
 2012/5/23 Jan Kara j...@suse.cz:
  On Sun 20-05-12 22:23:14, Akinobu Mita wrote:
  memweight() is the function that counts the total number of bits set
  in memory area.  The memory area doesn't need to be aligned to
  long-word boundary unlike bitmap_weight().
   Thanks for the patch. I have some comments below.
 
 Thanks for the review.
 
  @@ -824,3 +825,39 @@ void *memchr_inv(const void *start, int c, size_t 
  bytes)
        return check_bytes8(start, value, bytes % 8);
   }
   EXPORT_SYMBOL(memchr_inv);
  +
  +/**
  + * memweight - count the total number of bits set in memory area
  + * @ptr: pointer to the start of the area
  + * @bytes: the size of the area
  + */
  +size_t memweight(const void *ptr, size_t bytes)
  +{
  +     size_t w = 0;
  +     size_t longs;
  +     union {
  +             const void *ptr;
  +             const unsigned char *b;
  +             unsigned long address;
  +     } bitmap;
   Ugh, this is ugly and mostly unnecessary. Just use const unsigned char
  *bitmap.
 
  +
  +     for (bitmap.ptr = ptr; bytes  0  bitmap.address % sizeof(long);
  +                     bytes--, bitmap.address++)
  +             w += hweight8(*bitmap.b);
   This can be:
         count = ((unsigned long)bitmap) % sizeof(long);
 
 The count should be the size of unaligned area and it can be greater than
 bytes. So
 
 count = min(bytes,
 sizeof(long) - ((unsigned long)bitmap) % sizeof(long));
  You are right, I didn't quite think this through.
 
         while (count--) {
                 w += hweight(*bitmap);
                 bitmap++;
                 bytes--;
         }
  +
  +     for (longs = bytes / sizeof(long); longs  0; ) {
  +             size_t bits = min_t(size_t, INT_MAX  ~(BITS_PER_LONG - 1),
  +                                     longs * BITS_PER_LONG);
   I find it highly unlikely that someone would have such a large bitmap
  (256 MB or more on 32-bit). Also the condition as you wrote it can just
  overflow so it won't have the desired effect. Just do
         BUG_ON(longs = ULONG_MAX / BITS_PER_LONG);
 
 The bits argument of bitmap_weight() is int type. So this should be
 
 BUG_ON(longs = INT_MAX / BITS_PER_LONG);
  OK, I didn't check and thought it's size_t.

  and remove the loop completely. If someone comes with such a huge bitmap,
  the code can be modified easily (after really closely inspecting whether
  such a huge bitmap is really well justified).
 
 size_t memweight(const void *ptr, size_t bytes)
 {
   size_t w = 0;
   size_t longs;
   const unsigned char *bitmap = ptr;
 
   for (; bytes  0  ((unsigned long)bitmap) % sizeof(long);
   bytes--, bitmap++)
   w += hweight8(*bitmap);
 
   longs = bytes / sizeof(long);
   BUG_ON(longs = INT_MAX / BITS_PER_LONG);
   w += bitmap_weight((unsigned long *)bitmap, longs * BITS_PER_LONG);
   bytes -= longs * sizeof(long);
   bitmap += longs * sizeof(long);
 
   for (; bytes  0; bytes--, bitmap++)
   w += hweight8(*bitmap);
 
   return w;
 }
  Yup, this looks much more readable. Thanks!

Honza
  
-- 
Jan Kara j...@suse.cz
SUSE Labs, CR
--
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/12] Support for dmabuf exporting for videobuf2

2012-05-23 Thread Tomasz Stanislawski
Hello everyone,
The patches adds support for DMABUF exporting to V4L2 stack.  The latest
support for DMABUF importing was posted in [1]. The exporter part is dependant
on DMA mapping redesign [2] which is not merged into the mainline. Therefore it
is posted as a separate patchset. Moreover some patches depends on vmap
extension for DMABUF by Dave Airlie [3] and sg_alloc_table_from_pages function
[4].

Changelog:
v0: (RFC)
- updated setup of VIDIOC_EXPBUF ioctl
- doc updates
- introduced workaround to avoid using dma_get_pages,
- removed caching of exported dmabuf to avoid existence of circular reference
  between dmabuf and vb2_dc_buf or resource leakage
- removed all 'change behaviour' patches
- inital support for exporting in s5p-mfs driver
- removal of vb2_mmap_pfn_range that is no longer used
- use sg_alloc_table_from_pages instead of creating sglist in vb2_dc code
- move attachment allocation to exporter's attach callback

[1] http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/48730
[2] http://thread.gmane.org/gmane.linux.kernel.cross-arch/14098
[3] http://permalink.gmane.org/gmane.comp.video.dri.devel/69302
[4] This patchset is rebased on 3.4-rc1 plus the following patchsets:

Marek Szyprowski (1):
  v4l: vb2-dma-contig: let mmap method to use dma_mmap_coherent call

Tomasz Stanislawski (11):
  v4l: add buffer exporting via dmabuf
  v4l: vb2: add buffer exporting via dmabuf
  v4l: vb2-dma-contig: add setup of sglist for MMAP buffers
  v4l: vb2-dma-contig: add support for DMABUF exporting
  v4l: vb2-dma-contig: add vmap/kmap for dmabuf exporting
  v4l: s5p-fimc: support for dmabuf exporting
  v4l: s5p-tv: mixer: support for dmabuf exporting
  v4l: s5p-mfc: support for dmabuf exporting
  v4l: vb2: remove vb2_mmap_pfn_range function
  v4l: vb2-dma-contig: use sg_alloc_table_from_pages function
  v4l: vb2-dma-contig: Move allocation of dbuf attachment to attach cb

 drivers/media/video/s5p-fimc/fimc-capture.c |9 +
 drivers/media/video/s5p-mfc/s5p_mfc_dec.c   |   13 ++
 drivers/media/video/s5p-mfc/s5p_mfc_enc.c   |   13 ++
 drivers/media/video/s5p-tv/mixer_video.c|   10 +
 drivers/media/video/v4l2-compat-ioctl32.c   |1 +
 drivers/media/video/v4l2-dev.c  |1 +
 drivers/media/video/v4l2-ioctl.c|6 +
 drivers/media/video/videobuf2-core.c|   67 ++
 drivers/media/video/videobuf2-dma-contig.c  |  323 ++-
 drivers/media/video/videobuf2-memops.c  |   40 
 include/linux/videodev2.h   |   26 +++
 include/media/v4l2-ioctl.h  |2 +
 include/media/videobuf2-core.h  |2 +
 include/media/videobuf2-memops.h|5 -
 14 files changed, 411 insertions(+), 107 deletions(-)

-- 
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/12] v4l: s5p-fimc: support for dmabuf exporting

2012-05-23 Thread Tomasz Stanislawski
This patch enhances s5p-fimc with support for DMABUF exporting via
VIDIOC_EXPBUF ioctl.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
---
 drivers/media/video/s5p-fimc/fimc-capture.c |9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c 
b/drivers/media/video/s5p-fimc/fimc-capture.c
index cd27e33..52c9b36 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -1101,6 +1101,14 @@ static int fimc_cap_qbuf(struct file *file, void *priv,
return vb2_qbuf(fimc-vid_cap.vbq, buf);
 }
 
+static int fimc_cap_expbuf(struct file *file, void *priv,
+ struct v4l2_exportbuffer *eb)
+{
+   struct fimc_dev *fimc = video_drvdata(file);
+
+   return vb2_expbuf(fimc-vid_cap.vbq, eb);
+}
+
 static int fimc_cap_dqbuf(struct file *file, void *priv,
   struct v4l2_buffer *buf)
 {
@@ -1225,6 +1233,7 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops 
= {
 
.vidioc_qbuf= fimc_cap_qbuf,
.vidioc_dqbuf   = fimc_cap_dqbuf,
+   .vidioc_expbuf  = fimc_cap_expbuf,
 
.vidioc_prepare_buf = fimc_cap_prepare_buf,
.vidioc_create_bufs = fimc_cap_create_bufs,
-- 
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/12] v4l: vb2: add buffer exporting via dmabuf

2012-05-23 Thread Tomasz Stanislawski
This patch adds extension to videobuf2-core. It allow to export a mmap buffer
as a file descriptor.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
---
 drivers/media/video/videobuf2-core.c |   67 ++
 include/media/videobuf2-core.h   |2 +
 2 files changed, 69 insertions(+)

diff --git a/drivers/media/video/videobuf2-core.c 
b/drivers/media/video/videobuf2-core.c
index d60ed25..923165a 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -1730,6 +1730,73 @@ static int __find_plane_by_offset(struct vb2_queue *q, 
unsigned long off,
 }
 
 /**
+ * vb2_expbuf() - Export a buffer as a file descriptor
+ * @q: videobuf2 queue
+ * @eb:export buffer structure passed from userspace to 
vidioc_expbuf
+ * handler in driver
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_expbuf handler in driver.
+ */
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
+{
+   struct vb2_buffer *vb = NULL;
+   struct vb2_plane *vb_plane;
+   unsigned int buffer, plane;
+   int ret;
+   struct dma_buf *dbuf;
+
+   if (q-memory != V4L2_MEMORY_MMAP) {
+   dprintk(1, Queue is not currently set up for mmap\n);
+   return -EINVAL;
+   }
+
+   if (!q-mem_ops-get_dmabuf) {
+   dprintk(1, Queue does not support DMA buffer exporting\n);
+   return -EINVAL;
+   }
+
+   if (eb-flags  ~O_CLOEXEC) {
+   dprintk(1, Queue does support only O_CLOEXEC flag\n);
+   return -EINVAL;
+   }
+
+   /*
+* Find the plane corresponding to the offset passed by userspace.
+*/
+   ret = __find_plane_by_offset(q, eb-mem_offset, buffer, plane);
+   if (ret) {
+   dprintk(1, invalid offset %u\n, eb-mem_offset);
+   return ret;
+   }
+
+   vb = q-bufs[buffer];
+   vb_plane = vb-planes[plane];
+
+   dbuf = call_memop(q, get_dmabuf, vb_plane-mem_priv);
+   if (IS_ERR_OR_NULL(dbuf)) {
+   dprintk(1, Failed to export buffer %d, plane %d\n,
+   buffer, plane);
+   return -EINVAL;
+   }
+
+   ret = dma_buf_fd(dbuf, eb-flags);
+   if (ret  0) {
+   dprintk(3, buffer %d, plane %d failed to export (%d)\n,
+   buffer, plane, ret);
+   dma_buf_put(dbuf);
+   return ret;
+   }
+
+   dprintk(3, buffer %d, plane %d exported as %d descriptor\n,
+   buffer, plane, ret);
+   eb-fd = ret;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_expbuf);
+
+/**
  * vb2_mmap() - map video buffers into application address space
  * @q: videobuf2 queue
  * @vma:   vma passed to the mmap file operation handler in the driver
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index d079f92..fe01f95 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -81,6 +81,7 @@ struct vb2_fileio_data;
 struct vb2_mem_ops {
void*(*alloc)(void *alloc_ctx, unsigned long size);
void(*put)(void *buf_priv);
+   struct dma_buf *(*get_dmabuf)(void *buf_priv);
 
void*(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write);
@@ -350,6 +351,7 @@ int vb2_queue_init(struct vb2_queue *q);
 void vb2_queue_release(struct vb2_queue *q);
 
 int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b);
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb);
 int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);
 
 int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
-- 
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/12] v4l: vb2: remove vb2_mmap_pfn_range function

2012-05-23 Thread Tomasz Stanislawski
This patch removes vb2_mmap_pfn_range from videobuf2 helpers.
The function is no longer used in vb2 code.

Suggested-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
---
 drivers/media/video/videobuf2-memops.c |   40 
 include/media/videobuf2-memops.h   |5 
 2 files changed, 45 deletions(-)

diff --git a/drivers/media/video/videobuf2-memops.c 
b/drivers/media/video/videobuf2-memops.c
index 504cd4c..81c1ad8 100644
--- a/drivers/media/video/videobuf2-memops.c
+++ b/drivers/media/video/videobuf2-memops.c
@@ -137,46 +137,6 @@ int vb2_get_contig_userptr(unsigned long vaddr, unsigned 
long size,
 EXPORT_SYMBOL_GPL(vb2_get_contig_userptr);
 
 /**
- * vb2_mmap_pfn_range() - map physical pages to userspace
- * @vma:   virtual memory region for the mapping
- * @paddr: starting physical address of the memory to be mapped
- * @size:  size of the memory to be mapped
- * @vm_ops:vm operations to be assigned to the created area
- * @priv:  private data to be associated with the area
- *
- * Returns 0 on success.
- */
-int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
-   unsigned long size,
-   const struct vm_operations_struct *vm_ops,
-   void *priv)
-{
-   int ret;
-
-   size = min_t(unsigned long, vma-vm_end - vma-vm_start, size);
-
-   vma-vm_page_prot = pgprot_noncached(vma-vm_page_prot);
-   ret = remap_pfn_range(vma, vma-vm_start, paddr  PAGE_SHIFT,
-   size, vma-vm_page_prot);
-   if (ret) {
-   printk(KERN_ERR Remapping memory failed, error: %d\n, ret);
-   return ret;
-   }
-
-   vma-vm_flags   |= VM_DONTEXPAND | VM_RESERVED;
-   vma-vm_private_data= priv;
-   vma-vm_ops = vm_ops;
-
-   vma-vm_ops-open(vma);
-
-   pr_debug(%s: mapped paddr 0x%08lx at 0x%08lx, size %ld\n,
-   __func__, paddr, vma-vm_start, size);
-
-   return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_mmap_pfn_range);
-
-/**
  * vb2_common_vm_open() - increase refcount of the vma
  * @vma:   virtual memory region for the mapping
  *
diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h
index 84e1f6c..f05444c 100644
--- a/include/media/videobuf2-memops.h
+++ b/include/media/videobuf2-memops.h
@@ -33,11 +33,6 @@ extern const struct vm_operations_struct vb2_common_vm_ops;
 int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size,
   struct vm_area_struct **res_vma, dma_addr_t *res_pa);
 
-int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
-   unsigned long size,
-   const struct vm_operations_struct *vm_ops,
-   void *priv);
-
 struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma);
 void vb2_put_vma(struct vm_area_struct *vma);
 
-- 
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 01/12] v4l: vb2-dma-contig: let mmap method to use dma_mmap_coherent call

2012-05-23 Thread Tomasz Stanislawski
From: Marek Szyprowski m.szyprow...@samsung.com

Let mmap method to use dma_mmap_coherent call.  This patch depends on DMA
mapping redesign patches because the usage of dma_mmap_coherent breaks
dma-contig allocator for architectures other than ARM and AVR.

Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
---
 drivers/media/video/videobuf2-dma-contig.c |   28 ++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 9c213bc..52b4f59 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -224,14 +224,38 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
 static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
+   int ret;
 
if (!buf) {
printk(KERN_ERR No buffer to map\n);
return -EINVAL;
}
 
-   return vb2_mmap_pfn_range(vma, buf-dma_addr, buf-size,
- vb2_common_vm_ops, buf-handler);
+   /*
+* dma_mmap_* uses vm_pgoff as in-buffer offset, but we want to
+* map whole buffer
+*/
+   vma-vm_pgoff = 0;
+
+   ret = dma_mmap_coherent(buf-dev, vma, buf-vaddr,
+   buf-dma_addr, buf-size);
+
+   if (ret) {
+   printk(KERN_ERR Remapping memory failed, error: %d\n, ret);
+   return ret;
+   }
+
+   vma-vm_flags   |= VM_DONTEXPAND | VM_RESERVED;
+   vma-vm_private_data= buf-handler;
+   vma-vm_ops = vb2_common_vm_ops;
+
+   vma-vm_ops-open(vma);
+
+   printk(KERN_DEBUG %s: mapped dma addr 0x%08lx at 0x%08lx, size %ld\n,
+   __func__, (unsigned long)buf-dma_addr, vma-vm_start,
+   buf-size);
+
+   return 0;
 }
 
 /*/
-- 
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/12] v4l: s5p-mfc: support for dmabuf exporting

2012-05-23 Thread Tomasz Stanislawski
This patch enhances s5p-mfc with support for DMABUF exporting via
VIDIOC_EXPBUF ioctl.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
CC: Kamil Debski k.deb...@samsung.com
---
 drivers/media/video/s5p-mfc/s5p_mfc_dec.c |   13 +
 drivers/media/video/s5p-mfc/s5p_mfc_enc.c |   13 +
 2 files changed, 26 insertions(+)

diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c 
b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
index c25ec02..e1ebc76 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
@@ -564,6 +564,18 @@ static int vidioc_dqbuf(struct file *file, void *priv, 
struct v4l2_buffer *buf)
return -EINVAL;
 }
 
+/* Export DMA buffer */
+static int vidioc_expbuf(struct file *file, void *priv,
+   struct v4l2_exportbuffer *eb)
+{
+   struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+
+   if (eb-mem_offset  DST_QUEUE_OFF_BASE)
+   return vb2_expbuf(ctx-vq_src, eb);
+   else
+   return vb2_expbuf(ctx-vq_dst, eb);
+}
+
 /* Stream on */
 static int vidioc_streamon(struct file *file, void *priv,
   enum v4l2_buf_type type)
@@ -739,6 +751,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = {
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf,
+   .vidioc_expbuf = vidioc_expbuf,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_g_crop = vidioc_g_crop,
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c 
b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
index acedb20..887f1aa 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
@@ -1141,6 +1141,18 @@ static int vidioc_dqbuf(struct file *file, void *priv, 
struct v4l2_buffer *buf)
return -EINVAL;
 }
 
+/* Export DMA buffer */
+static int vidioc_expbuf(struct file *file, void *priv,
+   struct v4l2_exportbuffer *eb)
+{
+   struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+
+   if (eb-mem_offset  DST_QUEUE_OFF_BASE)
+   return vb2_expbuf(ctx-vq_src, eb);
+   else
+   return vb2_expbuf(ctx-vq_dst, eb);
+}
+
 /* Stream on */
 static int vidioc_streamon(struct file *file, void *priv,
   enum v4l2_buf_type type)
@@ -1486,6 +1498,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops 
= {
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf,
+   .vidioc_expbuf = vidioc_expbuf,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_s_parm = vidioc_s_parm,
-- 
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/12] v4l: vb2-dma-contig: add setup of sglist for MMAP buffers

2012-05-23 Thread Tomasz Stanislawski
This patch adds the setup of sglist list for MMAP buffers.
It is needed for buffer exporting via DMABUF mechanism.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
---
 drivers/media/video/videobuf2-dma-contig.c |   70 +++-
 1 file changed, 68 insertions(+), 2 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 52b4f59..ae656be 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -32,6 +32,7 @@ struct vb2_dc_buf {
/* MMAP related */
struct vb2_vmarea_handler   handler;
atomic_trefcount;
+   struct sg_table *sgt_base;
 
/* USERPTR related */
struct vm_area_struct   *vma;
@@ -189,14 +190,37 @@ static void vb2_dc_put(void *buf_priv)
if (!atomic_dec_and_test(buf-refcount))
return;
 
+   vb2_dc_release_sgtable(buf-sgt_base);
dma_free_coherent(buf-dev, buf-size, buf-vaddr, buf-dma_addr);
kfree(buf);
 }
 
+static int vb2_dc_kaddr_to_pages(unsigned long kaddr,
+   struct page **pages, unsigned int n_pages)
+{
+   unsigned int i;
+   unsigned long pfn;
+   struct vm_area_struct vma = {
+   .vm_flags = VM_IO | VM_PFNMAP,
+   .vm_mm = current-mm,
+   };
+
+   for (i = 0; i  n_pages; ++i, kaddr += PAGE_SIZE) {
+   if (follow_pfn(vma, kaddr, pfn))
+   break;
+   pages[i] = pfn_to_page(pfn);
+   }
+
+   return i;
+}
+
 static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
struct device *dev = alloc_ctx;
struct vb2_dc_buf *buf;
+   int ret = -ENOMEM;
+   int n_pages;
+   struct page **pages = NULL;
 
buf = kzalloc(sizeof *buf, GFP_KERNEL);
if (!buf)
@@ -205,10 +229,41 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
buf-vaddr = dma_alloc_coherent(dev, size, buf-dma_addr, GFP_KERNEL);
if (!buf-vaddr) {
dev_err(dev, dma_alloc_coherent of size %ld failed\n, size);
-   kfree(buf);
-   return ERR_PTR(-ENOMEM);
+   goto fail_buf;
+   }
+
+   WARN_ON((unsigned long)buf-vaddr  ~PAGE_MASK);
+   WARN_ON(buf-dma_addr  ~PAGE_MASK);
+
+   n_pages = PAGE_ALIGN(size)  PAGE_SHIFT;
+
+   pages = kmalloc(n_pages * sizeof pages[0], GFP_KERNEL);
+   if (!pages) {
+   dev_err(dev, failed to alloc page table\n);
+   goto fail_dma;
+   }
+
+   ret = vb2_dc_kaddr_to_pages((unsigned long)buf-vaddr, pages, n_pages);
+   if (ret  0) {
+   dev_err(dev, failed to get buffer pages from DMA API\n);
+   goto fail_pages;
+   }
+   if (ret != n_pages) {
+   ret = -EFAULT;
+   dev_err(dev, failed to get all pages from DMA API\n);
+   goto fail_pages;
+   }
+
+   buf-sgt_base = vb2_dc_pages_to_sgt(pages, n_pages, 0, size);
+   if (IS_ERR(buf-sgt_base)) {
+   ret = PTR_ERR(buf-sgt_base);
+   dev_err(dev, failed to prepare sg table\n);
+   goto fail_pages;
}
 
+   /* pages are no longer needed */
+   kfree(pages);
+
buf-dev = dev;
buf-size = size;
 
@@ -219,6 +274,17 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
atomic_inc(buf-refcount);
 
return buf;
+
+fail_pages:
+   kfree(pages);
+
+fail_dma:
+   dma_free_coherent(dev, size, buf-vaddr, buf-dma_addr);
+
+fail_buf:
+   kfree(buf);
+
+   return ERR_PTR(ret);
 }
 
 static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
-- 
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 11/12] v4l: vb2-dma-contig: use sg_alloc_table_from_pages function

2012-05-23 Thread Tomasz Stanislawski
This patch makes use of sg_alloc_table_from_pages to simplify
handling of sg tables.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
---
 drivers/media/video/videobuf2-dma-contig.c |   90 
 1 file changed, 25 insertions(+), 65 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 59ee81c..b5caf1d 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -32,7 +32,7 @@ struct vb2_dc_buf {
/* MMAP related */
struct vb2_vmarea_handler   handler;
atomic_trefcount;
-   struct sg_table *sgt_base;
+   struct sg_table sgt_base;
 
/* USERPTR related */
struct vm_area_struct   *vma;
@@ -45,57 +45,6 @@ struct vb2_dc_buf {
 /*scatterlist table functions*/
 /*/
 
-static struct sg_table *vb2_dc_pages_to_sgt(struct page **pages,
-   unsigned int n_pages, unsigned long offset, unsigned long size)
-{
-   struct sg_table *sgt;
-   unsigned int chunks;
-   unsigned int i;
-   unsigned int cur_page;
-   int ret;
-   struct scatterlist *s;
-
-   sgt = kzalloc(sizeof *sgt, GFP_KERNEL);
-   if (!sgt)
-   return ERR_PTR(-ENOMEM);
-
-   /* compute number of chunks */
-   chunks = 1;
-   for (i = 1; i  n_pages; ++i)
-   if (pages[i] != pages[i - 1] + 1)
-   ++chunks;
-
-   ret = sg_alloc_table(sgt, chunks, GFP_KERNEL);
-   if (ret) {
-   kfree(sgt);
-   return ERR_PTR(-ENOMEM);
-   }
-
-   /* merging chunks and putting them into the scatterlist */
-   cur_page = 0;
-   for_each_sg(sgt-sgl, s, sgt-orig_nents, i) {
-   unsigned long chunk_size;
-   unsigned int j;
-
-   for (j = cur_page + 1; j  n_pages; ++j)
-   if (pages[j] != pages[j - 1] + 1)
-   break;
-
-   chunk_size = ((j - cur_page)  PAGE_SHIFT) - offset;
-   sg_set_page(s, pages[cur_page], min(size, chunk_size), offset);
-   size -= chunk_size;
-   offset = 0;
-   cur_page = j;
-   }
-
-   return sgt;
-}
-
-static void vb2_dc_release_sgtable(struct sg_table *sgt)
-{
-   sg_free_table(sgt);
-   kfree(sgt);
-}
 
 static void vb2_dc_sgt_foreach_page(struct sg_table *sgt,
void (*cb)(struct page *pg))
@@ -190,7 +139,7 @@ static void vb2_dc_put(void *buf_priv)
if (!atomic_dec_and_test(buf-refcount))
return;
 
-   vb2_dc_release_sgtable(buf-sgt_base);
+   sg_free_table(buf-sgt_base);
dma_free_coherent(buf-dev, buf-size, buf-vaddr, buf-dma_addr);
kfree(buf);
 }
@@ -254,9 +203,9 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
goto fail_pages;
}
 
-   buf-sgt_base = vb2_dc_pages_to_sgt(pages, n_pages, 0, size);
-   if (IS_ERR(buf-sgt_base)) {
-   ret = PTR_ERR(buf-sgt_base);
+   ret = sg_alloc_table_from_pages(buf-sgt_base,
+   pages, n_pages, 0, size, GFP_KERNEL);
+   if (ret) {
dev_err(dev, failed to prepare sg table\n);
goto fail_pages;
}
@@ -379,13 +328,13 @@ static struct sg_table *vb2_dc_dmabuf_ops_map(
attach-dir = dir;
 
/* copying the buf-base_sgt to attachment */
-   ret = sg_alloc_table(sgt, buf-sgt_base-orig_nents, GFP_KERNEL);
+   ret = sg_alloc_table(sgt, buf-sgt_base.orig_nents, GFP_KERNEL);
if (ret) {
kfree(attach);
return ERR_PTR(-ENOMEM);
}
 
-   rd = buf-sgt_base-sgl;
+   rd = buf-sgt_base.sgl;
wr = sgt-sgl;
for (i = 0; i  sgt-orig_nents; ++i) {
sg_set_page(wr, sg_page(rd), rd-length, rd-offset);
@@ -519,7 +468,8 @@ static void vb2_dc_put_userptr(void *buf_priv)
if (!vma_is_io(buf-vma))
vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page);
 
-   vb2_dc_release_sgtable(sgt);
+   sg_free_table(sgt);
+   kfree(sgt);
vb2_put_vma(buf-vma);
kfree(buf);
 }
@@ -586,13 +536,20 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned 
long vaddr,
goto fail_vma;
}
 
-   sgt = vb2_dc_pages_to_sgt(pages, n_pages, offset, size);
-   if (IS_ERR(sgt)) {
-   printk(KERN_ERR failed to create scatterlist table\n);
+   sgt = kzalloc(sizeof *sgt, GFP_KERNEL);
+   if (!sgt) {
+   printk(KERN_ERR failed to allocate sg table\n);
ret = -ENOMEM;
goto fail_get_user_pages;
}
 
+   ret = sg_alloc_table_from_pages(sgt, pages, n_pages,
+   offset, size, 

[PATCH 05/12] v4l: vb2-dma-contig: add support for DMABUF exporting

2012-05-23 Thread Tomasz Stanislawski
This patch adds support for exporting a dma-contig buffer using
DMABUF interface.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
---
 drivers/media/video/videobuf2-dma-contig.c |  119 
 1 file changed, 119 insertions(+)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index ae656be..b5826e0 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -325,6 +325,124 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 }
 
 /*/
+/* DMABUF ops for exporters  */
+/*/
+
+struct vb2_dc_attachment {
+   struct sg_table sgt;
+   enum dma_data_direction dir;
+};
+
+static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
+   struct dma_buf_attachment *dbuf_attach)
+{
+   /* nothing to be done */
+   return 0;
+}
+
+static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf,
+   struct dma_buf_attachment *db_attach)
+{
+   struct vb2_dc_attachment *attach = db_attach-priv;
+   struct sg_table *sgt;
+
+   if (!attach)
+   return;
+
+   sgt = attach-sgt;
+
+   dma_unmap_sg(db_attach-dev, sgt-sgl, sgt-nents, attach-dir);
+   sg_free_table(sgt);
+   kfree(attach);
+   db_attach-priv = NULL;
+}
+
+static struct sg_table *vb2_dc_dmabuf_ops_map(
+   struct dma_buf_attachment *db_attach, enum dma_data_direction dir)
+{
+   struct dma_buf *dbuf = db_attach-dmabuf;
+   struct vb2_dc_buf *buf = dbuf-priv;
+   struct vb2_dc_attachment *attach = db_attach-priv;
+   struct sg_table *sgt;
+   struct scatterlist *rd, *wr;
+   int i, ret;
+
+   /* return previously mapped sg table */
+   if (attach)
+   return attach-sgt;
+
+   attach = kzalloc(sizeof *attach, GFP_KERNEL);
+   if (!attach)
+   return ERR_PTR(-ENOMEM);
+
+   sgt = attach-sgt;
+   attach-dir = dir;
+
+   /* copying the buf-base_sgt to attachment */
+   ret = sg_alloc_table(sgt, buf-sgt_base-orig_nents, GFP_KERNEL);
+   if (ret) {
+   kfree(attach);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   rd = buf-sgt_base-sgl;
+   wr = sgt-sgl;
+   for (i = 0; i  sgt-orig_nents; ++i) {
+   sg_set_page(wr, sg_page(rd), rd-length, rd-offset);
+   rd = sg_next(rd);
+   wr = sg_next(wr);
+   }
+
+   /* mapping new sglist to the client */
+   ret = dma_map_sg(db_attach-dev, sgt-sgl, sgt-orig_nents, dir);
+   if (ret = 0) {
+   printk(KERN_ERR failed to map scatterlist\n);
+   sg_free_table(sgt);
+   kfree(attach);
+   return ERR_PTR(-EIO);
+   }
+
+   db_attach-priv = attach;
+
+   return sgt;
+}
+
+static void vb2_dc_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach,
+   struct sg_table *sgt, enum dma_data_direction dir)
+{
+   /* nothing to be done here */
+}
+
+static void vb2_dc_dmabuf_ops_release(struct dma_buf *dbuf)
+{
+   /* drop reference obtained in vb2_dc_get_dmabuf */
+   vb2_dc_put(dbuf-priv);
+}
+
+static struct dma_buf_ops vb2_dc_dmabuf_ops = {
+   .attach = vb2_dc_dmabuf_ops_attach,
+   .detach = vb2_dc_dmabuf_ops_detach,
+   .map_dma_buf = vb2_dc_dmabuf_ops_map,
+   .unmap_dma_buf = vb2_dc_dmabuf_ops_unmap,
+   .release = vb2_dc_dmabuf_ops_release,
+};
+
+static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct dma_buf *dbuf;
+
+   dbuf = dma_buf_export(buf, vb2_dc_dmabuf_ops, buf-size, 0);
+   if (IS_ERR(dbuf))
+   return NULL;
+
+   /* dmabuf keeps reference to vb2 buffer */
+   atomic_inc(buf-refcount);
+
+   return dbuf;
+}
+
+/*/
 /*   callbacks for USERPTR buffers   */
 /*/
 
@@ -621,6 +739,7 @@ static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct 
dma_buf *dbuf,
 const struct vb2_mem_ops vb2_dma_contig_memops = {
.alloc  = vb2_dc_alloc,
.put= vb2_dc_put,
+   .get_dmabuf = vb2_dc_get_dmabuf,
.cookie = vb2_dc_cookie,
.vaddr  = vb2_dc_vaddr,
.mmap   = vb2_dc_mmap,
-- 
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 02/12] v4l: add buffer exporting via dmabuf

2012-05-23 Thread Tomasz Stanislawski
This patch adds extension to V4L2 api. It allow to export a mmap buffer as file
descriptor. New ioctl VIDIOC_EXPBUF is added. It takes a buffer offset used by
mmap and return a file descriptor on success.

Signed-off-by: Tomasz Stanislawski t.stanisl...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
---
 drivers/media/video/v4l2-compat-ioctl32.c |1 +
 drivers/media/video/v4l2-dev.c|1 +
 drivers/media/video/v4l2-ioctl.c  |6 ++
 include/linux/videodev2.h |   26 ++
 include/media/v4l2-ioctl.h|2 ++
 5 files changed, 36 insertions(+)

diff --git a/drivers/media/video/v4l2-compat-ioctl32.c 
b/drivers/media/video/v4l2-compat-ioctl32.c
index 5327ad3..45159d9 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -954,6 +954,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int 
cmd, unsigned long arg)
case VIDIOC_S_FBUF32:
case VIDIOC_OVERLAY32:
case VIDIOC_QBUF32:
+   case VIDIOC_EXPBUF:
case VIDIOC_DQBUF32:
case VIDIOC_STREAMON32:
case VIDIOC_STREAMOFF32:
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 5ccbd46..6bf6307 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -597,6 +597,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
+   SET_VALID_IOCTL(ops, VIDIOC_EXPBUF, vidioc_expbuf);
SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf);
SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay);
SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf);
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 31fc2ad..a73b14e 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -212,6 +212,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO(VIDIOC_S_FBUF, INFO_FL_PRIO),
IOCTL_INFO(VIDIOC_OVERLAY, INFO_FL_PRIO),
IOCTL_INFO(VIDIOC_QBUF, 0),
+   IOCTL_INFO(VIDIOC_EXPBUF, 0),
IOCTL_INFO(VIDIOC_DQBUF, 0),
IOCTL_INFO(VIDIOC_STREAMON, INFO_FL_PRIO),
IOCTL_INFO(VIDIOC_STREAMOFF, INFO_FL_PRIO),
@@ -957,6 +958,11 @@ static long __video_do_ioctl(struct file *file,
dbgbuf(cmd, vfd, p);
break;
}
+   case VIDIOC_EXPBUF:
+   {
+   ret = ops-vidioc_expbuf(file, fh, arg);
+   break;
+   }
case VIDIOC_DQBUF:
{
struct v4l2_buffer *p = arg;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 51b20f4..e8893a5 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -684,6 +684,31 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE  0x0800
 #define V4L2_BUF_FLAG_NO_CACHE_CLEAN   0x1000
 
+/**
+ * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor
+ *
+ * @fd:file descriptor associated with DMABUF (set by driver)
+ * @mem_offset:buffer memory offset as returned by VIDIOC_QUERYBUF in 
struct
+ * v4l2_buffer::m.offset (for single-plane formats) or
+ * v4l2_plane::m.offset (for multi-planar formats)
+ * @flags: flags for newly created file, currently only O_CLOEXEC is
+ * supported, refer to manual of open syscall for more details
+ *
+ * Contains data used for exporting a video buffer as DMABUF file descriptor.
+ * The buffer is identified by a 'cookie' returned by VIDIOC_QUERYBUF
+ * (identical to the cookie used to mmap() the buffer to userspace). All
+ * reserved fields must be set to zero. The field reserved0 is expected to
+ * become a structure 'type' allowing an alternative layout of the structure
+ * content. Therefore this field should not be used for any other extensions.
+ */
+struct v4l2_exportbuffer {
+   __u32   fd;
+   __u32   reserved0;
+   __u32   mem_offset;
+   __u32   flags;
+   __u32   reserved[12];
+};
+
 /*
  * O V E R L A Y   P R E V I E W
  */
@@ -2553,6 +2578,7 @@ struct v4l2_create_buffers {
 #define VIDIOC_S_FBUF   _IOW('V', 11, struct v4l2_framebuffer)
 #define VIDIOC_OVERLAY  _IOW('V', 14, int)
 #define VIDIOC_QBUF_IOWR('V', 15, struct v4l2_buffer)
+#define VIDIOC_EXPBUF  _IOWR('V', 16, struct v4l2_exportbuffer)
 #define VIDIOC_DQBUF   _IOWR('V', 17, struct v4l2_buffer)
 #define VIDIOC_STREAMON _IOW('V', 18, int)
 #define VIDIOC_STREAMOFF_IOW('V', 19, int)
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index d8b76f7..ccd1faa 100644
--- a/include/media/v4l2-ioctl.h

[PATCH 2/8] soc-camera: Pass the physical device to the power operation

2012-05-23 Thread Laurent Pinchart
There will be no soc_camera_device instance with a soc-camera device is
used with a non soc-camera host, so we won't be able to pass the
soc_camera_device fake platform device to board code. Pass the physical
device instead.

The argument is currently not used by any board file so this is safe.

Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/soc_camera.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index e7c6809..b03ffec 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -62,7 +62,7 @@ static int soc_camera_power_on(struct soc_camera_device *icd,
}
 
if (icl-power) {
-   ret = icl-power(icd-pdev, 1);
+   ret = icl-power(icd-control, 1);
if (ret  0) {
dev_err(icd-pdev,
Platform failed to power-on the camera.\n);
@@ -78,7 +78,7 @@ static int soc_camera_power_on(struct soc_camera_device *icd,
 
 esdpwr:
if (icl-power)
-   icl-power(icd-pdev, 0);
+   icl-power(icd-control, 0);
 elinkpwr:
regulator_bulk_disable(icl-num_regulators,
   icl-regulators);
@@ -95,7 +95,7 @@ static int soc_camera_power_off(struct soc_camera_device *icd,
return ret;
 
if (icl-power) {
-   ret = icl-power(icd-pdev, 0);
+   ret = icl-power(icd-control, 0);
if (ret  0) {
dev_err(icd-pdev,
Platform failed to power-off the camera.\n);
-- 
1.7.3.4

--
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 8/8] soc-camera: Push probe-time power management to drivers

2012-05-23 Thread Laurent Pinchart
Several client drivers access the hardware at probe time, for instance
to read the probe chip ID. Such chips need to be powered up when being
probed.

soc-camera handles this by powering chips up in the soc-camera probe
implementation. However, this will break with non soc-camera hosts that
don't perform the same operations.

Fix the problem by pushing the power up/down from the soc-camera core
down to individual drivers on a needs basis.

Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/imx074.c |   21 --
 drivers/media/video/mt9m001.c|   17 +++-
 drivers/media/video/mt9m111.c|   80 +
 drivers/media/video/mt9t031.c|   18 ++---
 drivers/media/video/mt9t112.c|   12 +-
 drivers/media/video/mt9v022.c|5 ++
 drivers/media/video/ov2640.c |   11 -
 drivers/media/video/ov5642.c |   21 --
 drivers/media/video/ov6650.c |   19 ++---
 drivers/media/video/ov772x.c |   14 ++-
 drivers/media/video/ov9640.c |   17 ++--
 drivers/media/video/ov9740.c |   23 +++
 drivers/media/video/rj54n1cb0c.c |   18 ++--
 drivers/media/video/soc_camera.c |   14 ---
 drivers/media/video/tw9910.c |   12 +-
 15 files changed, 201 insertions(+), 101 deletions(-)

diff --git a/drivers/media/video/imx074.c b/drivers/media/video/imx074.c
index 1166c89..fc86e68 100644
--- a/drivers/media/video/imx074.c
+++ b/drivers/media/video/imx074.c
@@ -313,26 +313,33 @@ static struct v4l2_subdev_ops imx074_subdev_ops = {
 
 static int imx074_video_probe(struct i2c_client *client)
 {
+   struct v4l2_subdev *subdev = i2c_get_clientdata(client);
int ret;
u16 id;
 
+   ret = imx074_s_power(subdev, 1);
+   if (ret  0)
+   return ret;
+
/* Read sensor Model ID */
ret = reg_read(client, 0);
if (ret  0)
-   return ret;
+   goto done;
 
id = ret  8;
 
ret = reg_read(client, 1);
if (ret  0)
-   return ret;
+   goto done;
 
id |= ret;
 
dev_info(client-dev, Chip ID 0x%04x detected\n, id);
 
-   if (id != 0x74)
-   return -ENODEV;
+   if (id != 0x74) {
+   ret = -ENODEV;
+   goto done;
+   }
 
/* PLL Setting EXTCLK=24MHz, 22.5times */
reg_write(client, PLL_MULTIPLIER, 0x2D);
@@ -414,7 +421,11 @@ static int imx074_video_probe(struct i2c_client *client)
 
reg_write(client, GROUPED_PARAMETER_HOLD, 0x00);/* off */
 
-   return 0;
+   ret = 0;
+
+done:
+   imx074_s_power(subdev, 0);
+   return ret;
 }
 
 static int imx074_probe(struct i2c_client *client,
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index cf2aa00..b69bb91 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -493,6 +493,10 @@ static int mt9m001_video_probe(struct soc_camera_link *icl,
unsigned long flags;
int ret;
 
+   ret = mt9m001_s_power(mt9m001-subdev, 1);
+   if (ret  0)
+   return ret;
+
/* Enable the chip */
data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
dev_dbg(client-dev, write: %d\n, data);
@@ -514,7 +518,8 @@ static int mt9m001_video_probe(struct soc_camera_link *icl,
default:
dev_err(client-dev,
No MT9M001 chip detected, register read %x\n, data);
-   return -ENODEV;
+   ret = -ENODEV;
+   goto done;
}
 
mt9m001-num_fmts = 0;
@@ -543,11 +548,17 @@ static int mt9m001_video_probe(struct soc_camera_link 
*icl,
 data == 0x8431 ? C12STM : C12ST);
 
ret = mt9m001_init(client);
-   if (ret  0)
+   if (ret  0) {
dev_err(client-dev, Failed to initialise the camera\n);
+   goto done;
+   }
 
/* mt9m001_init() has reset the chip, returning registers to defaults */
-   return v4l2_ctrl_handler_setup(mt9m001-hdl);
+   ret = v4l2_ctrl_handler_setup(mt9m001-hdl);
+
+done:
+   mt9m001_s_power(mt9m001-subdev, 0);
+   return ret;
 }
 
 static void mt9m001_video_remove(struct soc_camera_link *icl)
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index b9bfb4f..36dd39f 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -797,41 +797,6 @@ static int mt9m111_init(struct mt9m111 *mt9m111)
return ret;
 }
 
-/*
- * Interface active, can use i2c. If it fails, it can indeed mean, that
- * this wasn't our capture interface, so, we wait for the right one
- */
-static int mt9m111_video_probe(struct i2c_client *client)
-{
-   struct mt9m111 *mt9m111 = to_mt9m111(client);
-   s32 data;
-   int ret;
-
-   data = reg_read(CHIP_VERSION);
-
-   switch (data) {
-   case 0x143a: /* MT9M111 or MT9M131 */
-  

[PATCH 6/8] soc_camera: Don't call .s_power() during probe

2012-05-23 Thread Laurent Pinchart
The .s_power() call only covers the .g_mbus_fmt() operation call.
Several clients required to be powered on to retrieve the current mbus
format but have now been fixed. The .s_power() call is thus not needed
anymore and can be removed.

Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/soc_camera.c |6 --
 1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index b03ffec..55b981f 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -1133,10 +1133,6 @@ static int soc_camera_probe(struct soc_camera_device 
*icd)
if (ret  0)
goto evidstart;
 
-   ret = v4l2_subdev_call(sd, core, s_power, 1);
-   if (ret  0  ret != -ENOIOCTLCMD)
-   goto esdpwr;
-
/* Try to improve our guess of a reasonable window format */
if (!v4l2_subdev_call(sd, video, g_mbus_fmt, mf)) {
icd-user_width = mf.width;
@@ -1153,8 +1149,6 @@ static int soc_camera_probe(struct soc_camera_device *icd)
 
return 0;
 
-esdpwr:
-   video_unregister_device(icd-vdev);
 evidstart:
mutex_unlock(icd-video_lock);
soc_camera_free_user_formats(icd);
-- 
1.7.3.4

--
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 7/8] soc-camera: Add and use soc_camera_power_[on|off]() helper functions

2012-05-23 Thread Laurent Pinchart
Instead of forcing all soc-camera drivers to go through the mid-layer to
handle power management, create soc_camera_power_[on|off]() functions
that can be called from the subdev .s_power() operation to manage
regulators and platform-specific power handling. This allows non
soc-camera hosts to use soc-camera-aware clients.

Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/imx074.c  |   12 
 drivers/media/video/mt9m001.c |   12 
 drivers/media/video/mt9m111.c |   50 +++-
 drivers/media/video/mt9t031.c |   11 +++-
 drivers/media/video/mt9t112.c |   12 
 drivers/media/video/mt9v022.c |   12 
 drivers/media/video/ov2640.c  |   12 
 drivers/media/video/ov5642.c  |   11 +++-
 drivers/media/video/ov6650.c  |   12 
 drivers/media/video/ov772x.c  |   12 
 drivers/media/video/ov9640.c  |   13 -
 drivers/media/video/ov9740.c  |   15 +-
 drivers/media/video/rj54n1cb0c.c  |   12 
 drivers/media/video/sh_mobile_csi2.c  |   10 +++-
 drivers/media/video/soc_camera.c  |   90 +++-
 drivers/media/video/soc_camera_platform.c |   15 +-
 drivers/media/video/tw9910.c  |   12 
 include/media/soc_camera.h|2 +
 18 files changed, 260 insertions(+), 65 deletions(-)

diff --git a/drivers/media/video/imx074.c b/drivers/media/video/imx074.c
index 351e9ba..1166c89 100644
--- a/drivers/media/video/imx074.c
+++ b/drivers/media/video/imx074.c
@@ -268,6 +268,17 @@ static int imx074_g_chip_ident(struct v4l2_subdev *sd,
return 0;
 }
 
+static int imx074_s_power(struct v4l2_subdev *sd, int on)
+{
+   struct i2c_client *client = v4l2_get_subdevdata(sd);
+   struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+   if (on)
+   return soc_camera_power_on(client-dev, icl);
+   else
+   return soc_camera_power_off(client-dev, icl);
+}
+
 static int imx074_g_mbus_config(struct v4l2_subdev *sd,
struct v4l2_mbus_config *cfg)
 {
@@ -292,6 +303,7 @@ static struct v4l2_subdev_video_ops imx074_subdev_video_ops 
= {
 
 static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
.g_chip_ident   = imx074_g_chip_ident,
+   .s_power= imx074_s_power,
 };
 
 static struct v4l2_subdev_ops imx074_subdev_ops = {
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 7e64818..cf2aa00 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -377,6 +377,17 @@ static int mt9m001_s_register(struct v4l2_subdev *sd,
 }
 #endif
 
+static int mt9m001_s_power(struct v4l2_subdev *sd, int on)
+{
+   struct i2c_client *client = v4l2_get_subdevdata(sd);
+   struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+   if (on)
+   return soc_camera_power_on(client-dev, icl);
+   else
+   return soc_camera_power_off(client-dev, icl);
+}
+
 static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 {
struct mt9m001 *mt9m001 = container_of(ctrl-handler,
@@ -566,6 +577,7 @@ static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops 
= {
.g_register = mt9m001_g_register,
.s_register = mt9m001_s_register,
 #endif
+   .s_power= mt9m001_s_power,
 };
 
 static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index b0c5299..b9bfb4f 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -832,10 +832,35 @@ static int mt9m111_video_probe(struct i2c_client *client)
return v4l2_ctrl_handler_setup(mt9m111-hdl);
 }
 
+static int mt9m111_power_on(struct mt9m111 *mt9m111)
+{
+   struct i2c_client *client = v4l2_get_subdevdata(mt9m111-subdev);
+   struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+   int ret;
+
+   ret = soc_camera_power_on(client-dev, icl);
+   if (ret  0)
+   return ret;
+
+   ret = mt9m111_resume(mt9m111);
+   if (ret  0)
+   dev_err(client-dev, Failed to resume the sensor: %d\n, ret);
+
+   return ret;
+}
+
+static void mt9m111_power_off(struct mt9m111 *mt9m111)
+{
+   struct i2c_client *client = v4l2_get_subdevdata(mt9m111-subdev);
+   struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
+
+   mt9m111_suspend(mt9m111);
+   soc_camera_power_off(client-dev, icl);
+}
+
 static int mt9m111_s_power(struct v4l2_subdev *sd, int on)
 {
struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
-   struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
 
mutex_lock(mt9m111-power_lock);
@@ -845,23 +870,18 @@ static int mt9m111_s_power(struct v4l2_subdev *sd, int 

[PATCH 5/8] tw9910: Don't access the device in the g_mbus_fmt operation

2012-05-23 Thread Laurent Pinchart
The g_mbus_fmt operation only needs to return the current mbus frame
format and doesn't need to configure the hardware to do so. Fix it to
avoid requiring the chip to be powered on when calling the operation.

Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/tw9910.c |8 +++-
 1 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index 8768efb..9f53eac 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -699,11 +699,9 @@ static int tw9910_g_fmt(struct v4l2_subdev *sd,
struct tw9910_priv *priv = to_tw9910(client);
 
if (!priv-scale) {
-   int ret;
-   u32 width = 640, height = 480;
-   ret = tw9910_set_frame(sd, width, height);
-   if (ret  0)
-   return ret;
+   priv-scale = tw9910_select_norm(priv-norm, 640, 480);
+   if (!priv-scale)
+   return -EINVAL;
}
 
mf-width   = priv-scale-width;
-- 
1.7.3.4

--
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 4/8] ov772x: Don't access the device in the g_mbus_fmt operation

2012-05-23 Thread Laurent Pinchart
The g_mbus_fmt operation only needs to return the current mbus frame
format and doesn't need to configure the hardware to do so. Fix it to
avoid requiring the chip to be powered on when calling the operation.

Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/ov772x.c |8 ++--
 1 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 74e77d3..6d79b89 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -880,15 +880,11 @@ static int ov772x_cropcap(struct v4l2_subdev *sd, struct 
v4l2_cropcap *a)
 static int ov772x_g_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf)
 {
-   struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
 
if (!priv-win || !priv-cfmt) {
-   u32 width = VGA_WIDTH, height = VGA_HEIGHT;
-   int ret = ov772x_set_params(client, width, height,
-   V4L2_MBUS_FMT_YUYV8_2X8);
-   if (ret  0)
-   return ret;
+   priv-cfmt = ov772x_cfmts[0];
+   priv-win = ov772x_select_win(VGA_WIDTH, VGA_HEIGHT);
}
 
mf-width   = priv-win-width;
-- 
1.7.3.4

--
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/8] soc-camera: Don't fail at module init time if no device is present

2012-05-23 Thread Laurent Pinchart
The soc-camera module exports functions that are needed by soc-camera
client drivers even when not running in soc-camera mode. Replace the
platform_driver_probe() with a platform_driver_register() call to avoid
module load failures if no soc-camera device is present.

Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/soc_camera.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 0421bf9..e7c6809 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -1518,6 +1518,7 @@ static int __devexit soc_camera_pdrv_remove(struct 
platform_device *pdev)
 }
 
 static struct platform_driver __refdata soc_camera_pdrv = {
+   .probe = soc_camera_pdrv_probe,
.remove  = __devexit_p(soc_camera_pdrv_remove),
.driver  = {
.name   = soc-camera-pdrv,
@@ -1527,7 +1528,7 @@ static struct platform_driver __refdata soc_camera_pdrv = 
{
 
 static int __init soc_camera_init(void)
 {
-   return platform_driver_probe(soc_camera_pdrv, soc_camera_pdrv_probe);
+   return platform_driver_register(soc_camera_pdrv);
 }
 
 static void __exit soc_camera_exit(void)
-- 
1.7.3.4

--
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/8] Miscellaneous soc-camera patches

2012-05-23 Thread Laurent Pinchart
Hi Guennadi,

Here's a set of miscellaneous soc-camera patches that I wrote as part of an
effort to improve the interoperability between soc-camera clients and non
soc-camera hosts (namely the ov772x and the OMAP3 ISP in this case).

All patches have been compile-tested but not runtime-tested as I lack the
necessary hardware. I'd like to first validate the approach, I can then of
course fix any small (or not-so-small) issue you will point out.

Laurent Pinchart (8):
  soc-camera: Don't fail at module init time if no device is present
  soc-camera: Pass the physical device to the power operation
  ov2640: Don't access the device in the g_mbus_fmt operation
  ov772x: Don't access the device in the g_mbus_fmt operation
  tw9910: Don't access the device in the g_mbus_fmt operation
  soc_camera: Don't call .s_power() during probe
  soc-camera: Add and use soc_camera_power_[on|off]() helper functions
  soc-camera: Push probe-time power management to drivers

 drivers/media/video/imx074.c  |   33 +++-
 drivers/media/video/mt9m001.c |   29 +++-
 drivers/media/video/mt9m111.c |  116 ++---
 drivers/media/video/mt9t031.c |   29 +--
 drivers/media/video/mt9t112.c |   24 ++-
 drivers/media/video/mt9v022.c |   17 
 drivers/media/video/ov2640.c  |   28 +--
 drivers/media/video/ov5642.c  |   32 ++--
 drivers/media/video/ov6650.c  |   31 ++--
 drivers/media/video/ov772x.c  |   34 +++--
 drivers/media/video/ov9640.c  |   30 ++-
 drivers/media/video/ov9740.c  |   38 +++---
 drivers/media/video/rj54n1cb0c.c  |   30 ++-
 drivers/media/video/sh_mobile_csi2.c  |   10 ++-
 drivers/media/video/soc_camera.c  |  107 ---
 drivers/media/video/soc_camera_platform.c |   15 -
 drivers/media/video/tw9910.c  |   32 ++--
 include/media/soc_camera.h|2 +
 18 files changed, 459 insertions(+), 178 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


Discussion: How to deal with radio tuners which can tune to multiple bands

2012-05-23 Thread Hans de Goede

Hi,

As discussed before 2 different use-cases have come up where we want some
knowledge of there being different radio bands added to the v4l2 API.

In Manjunatha Halli's case, if I understand things correctly, he wants
to limit hw_freq_seek to a certain band, rather then the receiver happily
trying to seek to frequencies which are not relevant for the use case in
question. To that purpose his patch proposes adding a band field to the
v4l2_hw_freq_seek struct, which can have one of the following values:

FM_BAND_TYPE_ALLAll Bands from 65.8 MHz till 108 Mhz or 162.55 MHz if 
weather band
FM_BAND_TYPE_EUROPE_US  Europe or US band(87.5 Mhz - 108 MHz)
FM_BAND_TYPE_JAPAN  Japan band(76 MHz - 90 MHz)
FM_BAND_TYPE_RUSSIANOIRT or Russian band(65.8 MHz - 74 MHz)
FM_BAND_TYPE_WEATHERWeather band(162.4 MHz - 162.55 MHz)

In my case the problem is that the TEA5757 tuner can tune both AM
and FM (but note at the same time, it is a single tuner):
AM  530   - 1710 kHz
FM   87.5 -  108 MHz

In my case part of the problem is that the userspace UI for the tuner
cannot simply depict the frequency range as one large slider.

For FM devices having a slider going from 65.8 - 162.55 MHz is
far from ideal, esp. as there is a large whole of nothing in the
108-162 Mhz making the non functional area of the sliders range
larger then the functional area.

For AM and FM capable devices representing the entire range
(530 Khz - 162.55 Mhz) is not just not ideal it is simply unworkable!

So we don't just want to limit the range a VIDIOC_S_HW_FREQ_SEEK can
seek over, we also want to let user space know for manual tuning
that we've several ranges, and allow it to query information
such as min / max freq, stereo capable, etc. per range.

As discussed with Hans V. this can best be done by extending
struct v4l2_tuner with a band field.

Our (Hans V. and me) first idea here was to let this field
work like an index, where userspace can enumerate available
bands by calling VIDIOC_G_TUNER, incrementing band each time until
-EINVAL gets returned.

So that completes the intro, also known as setting the stage :)

###

Taking the intersection between the 2 proposals and the 2 problems
makes things interesting :)

Dividing the VIDIOC_G_TUNER results into bands also makes sense for
the FM case, at least in a 65.8 - 108 Mhz and a  162 Mhz band, to
avoid having a not tunable gap in the range reported to userspace.

But, allowing a EU citizen to tune below 87.5 is also not really
useful, nor allowing a Japanese citizen to tune above the 90 Mhz, etc.

So from presenting the user with a sensible UI pov, it makes sense
to not use 2 bands with FM, but to expose all supported bands
to userspace as they really are. This also makes sense from a demod
pov, since FM demodulation for Japanese FM is different then for
EU/US FM, so maybe the hardware needs to be poked to switch modes.

Note that some radio chip drivers already do this effectively by having
a module parameter to select which band to use.

So lets expose all the FM bands from Manjunatha Halli's proposal
in VIDIOC_G_TUNER results. If we then go for the classic enumeration
strategy where userspace can enumerate available bands by calling
VIDIOC_G_TUNER, incrementing band each time until -EINVAL gets
returned, we get another problem...

How does user space know which band is which (other then checking
min/max frequency which is ugly!) ? We could make the tuner name field
different for each band, and let the app display a menu with tuner names
for the user to select a band, but that is ugly too.

Not only would doing something like that be ugly, it also makes it
as good as impossible for userspace to automatically select the
right band based on location.

So doing the classic v4l2 enum trick where we increment band each
time until we get -EINVAL is not a good idea IMHO.

Luckily Manjunatha Halli's proposal already gives us a solution,
we can define a fixed set of bands (adding SW/MW/LW bands for AM),
and userspace can enumerate by trying a G_TUNER for all
bands it is interested in.

###

So given all of the above I would like to propose the following:

1) Add a band field to struct v4l2_tuner, and a capability
   indicating if the driver understands / uses this field
2) This field is only valid for radio tuners, for tv tuners it
should always be 0 (as it was sofar as it is reserved atm)
3) This field can have a number of fixed values, for now we have:

0 RADIO_BAND_DEFAULTEntire FM band supported by the tuner, or default
band if different bands require switching the tuner to
a different mode, or entire AM band supported by the
tuner for AM only tuners.
1 RADIO_BAND_FM_EUROPE_US Europe or US band(87.5 Mhz - 108 MHz) *
2 RADIO_BAND_FM_JAPAN   Japan band(76 MHz - 90 MHz) *
3 RADIO_BAND_FM_RUSSIAN OIRT or Russian band(65.8 MHz - 74 MHz) *
4 RADIO_BAND_FM_WEATHER Weather band(162.4 MHz - 162.55 MHz) *

256 

Re: Discussion: How to deal with radio tuners which can tune to multiple bands

2012-05-23 Thread Hans de Goede

Hi,

On 05/23/2012 09:24 PM, halli manjunatha wrote:

On Wed, May 23, 2012 at 1:29 PM, Hans de Goedehdego...@redhat.com  wrote:


 snip my super long proposal intro :) 


###

So given all of the above I would like to propose the following:

1) Add a band field to struct v4l2_tuner, and a capability
   indicating if the driver understands / uses this field
2) This field is only valid for radio tuners, for tv tuners it
should always be 0 (as it was sofar as it is reserved atm)
3) This field can have a number of fixed values, for now we have:

0 RADIO_BAND_DEFAULTEntire FM band supported by the tuner, or default
band if different bands require switching the tuner
to
a different mode, or entire AM band supported by the
tuner for AM only tuners.
1 RADIO_BAND_FM_EUROPE_US Europe or US band(87.5 Mhz - 108 MHz) *
2 RADIO_BAND_FM_JAPAN   Japan band(76 MHz - 90 MHz) *
3 RADIO_BAND_FM_RUSSIAN OIRT or Russian band(65.8 MHz - 74 MHz) *
4 RADIO_BAND_FM_WEATHER Weather band(162.4 MHz - 162.55 MHz) *

256 RADIO_BAND_AM_MWMid Wave AM band, covered frequencies are tuner
dependent
257 RADIO_BAND_AM_LWLong Wave AM band, covered frequencies are tuner
dependent
258 RADIO_BAND_AM_SWShort Wave AM band, covered frequencies are tuner
dependent


First - Here driver will add the list of Band which it supports in the
VIDEOC_G_TUNER capability flag


We could do that, although then the indexes for the AM bands need to be
lowered. I'm not sure if we should do this though. It will save a number
of ioctl calls, but those are cheap (as long as they don't hit the hardware)
and they are only done during enumeration by the app (iow not repeatedly)

So we've a trade-off here between making it easier for the app (the app
has to do less ioctls and can just test capability bits) and between
being conservative with capability bits.

I've a slight preference for the just let the app call g_tuner a number
of times to find out about supported bands because we don't know what
sort of bands we will add in the future and if we get too many bands
we may run out of capability bits.

With that said I'm not against the capability bits approach, just explaining
my reasoning. If Hans V. says he prefers the capability bits too, I'm fine
with going that way.



*) Reported (and available) frequency range might be different based on
hardware
capabilities

Notice how 0, which the current reserved field should be set to for old
apps,
should always cover as much of FM as possible, or AM for AM only tuners, to
preserve functionality for old non band aware v4l2 radio apps.

A (radio) tuner should always support RADIO_BAND_DEFAULT

4) Apps can find out which bands are supported by doing a VIDIOC_G_TUNER
with band set to the desired value. If the passed band is not available
-EINVAL will be returned.

Second - User Application do VIDEOC_G_TUNER and checks the struct
v4l2_tuner.capability for the list of bands supported by Driver.


See above :)



5) Apps can select the active band by doing a VIDIOC_S_TUNER with the band
field set to the desired band.

Third - Here App sets the chip  to the required band.


Ack.


6) Doing a VIDIOC_S_FREQUENCY with a frequency which falls outside of the
current band will *not* result in an automatic band switch, instead the
passed frequency will be clamped to fit into the current band.

Fourth - As already chip is set to a band set_frequency for frequency
within the activated band will work.

But I think its better to report 'ERANGE' to the frequencies which are
out of band limit. So that UI app also knows that set frequency failed
and it will show the bar to the last frequency.


The spec currently states that the behavior for s_freq is to set the
frequency to the nearest supported frequency, rather then report an error,
so we're stuck with that. Also note that the driver may also change the
frequency even if it is inside the range, because the hardware may not
be able to do the exact requested frequency. So any good written app
should always do a g_freq after a s_freq and show the user what he
actually got.



7) Doing a VIDIOC_S_HW_FREQ_SEEK will seek in the currently active band,
this matches existing behavior where the seek starts at the currently
active frequency.

I agree.


I think / hope that covers everything we need. Suggestions ? Comments ?


Solution seems fine for me


I'm happy to hear that!

Regards,

Hans
--
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: HVR1600 and Centos 6.2 x86_64 -- Strange Behavior

2012-05-23 Thread Bob Lightfoot
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 05/22/2012 06:06 PM, Andy Walls wrote:
 Devin Heitmueller dheitmuel...@kernellabs.com wrote:
 
 On Tue, May 22, 2012 at 4:34 PM, Bob Lightfoot
 boblf...@gmail.com wrote:
 -BEGIN PGP SIGNED MESSAGE- Hash: SHA1
 
 Dear LinuxTv and AtRpms Communities: In the most recent three
 kernels {2.6.32-220.7.1 ; 2.6.32-220.13.1 ; 2.6.32-220.17.1}
 released for CentOS 6.2 I have experienced what can only be
 described as a strange behavior of the V4L kernel modules with
 the Hauppage HVR 1600 Card.  If I reboot the PC in question {HP
 Pavillion Elite M9040n} I will lose sound on the Analog TV
 Tuner.  If I Power off the PC, leave it off for 30-60 seconds
 and start it back up then I have sound with the Analog TV Tuner
 every time.  Not sure what is causing this, but thought the 
 condition was worth sharing.
 
 Could you please clarify which HVR-1600 board you have (e.g. the
 PCI ID)?  I suspect we're probably not resetting the audio
 processor properly, but I would need to know exactly which board
 you have in order to check that.
 
 Devin
 
 -- Devin J. Heitmueller - Kernel Labs http://www.kernellabs.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
 
 Also, if you not done so already, verify that it is not a sound
 card playback issue.   Make a recording when you suspect the
 HVR1600 is not capturing sound. Then play the recording when you
 know your sound is working.
 
 Also, does audio line in with Svideo or CVBS exhibit the same
 symptoms?
 
 I had to go through a good bit of trial and error to get the
 CX23418's APU to capture audio reliably after boot up, so I am
 reluctant to mess with that unless needed.
 
 We will want to try to narrow the problem down to one of the analog
 tuner, integrated CX25843, or APU.
 
 Regards, Andy
 
First Question the PCI ID -- the output of lspci -v is :
01:00.0 Multimedia video controller: Conexant Systems, Inc. CX23418
Single-Chip MPEG-2 Encoder with Integrated Analog Video/Broadcast
Audio Decoder
Subsystem: Hauppauge computer works Inc. WinTV HVR-1600
Flags: bus master, medium devsel, latency 64, IRQ 17
Memory at f400 (32-bit, non-prefetchable) [size=64M]
Capabilities: [44] Vital Product Data
Capabilities: [4c] Power Management version 2
Kernel driver in use: cx18
Kernel modules: cx18

And although right now I cannot find the earlier instructions I
followed there was a post on the gossamer threads about the audio not
being detected and the card muting the output.  There was a command
{memory fails me right now} to query the card for the status of the
tuner which is showing the audio is undetermined and muted when this
issue happens.  It happens in both mythtv and cat  file.avi
recordings played back later.  It should be noted that audio playback
is fine despite the analog video sound being muted.

Bob Lightfoot

P.S. -- David  Andy - If you need more specific information just send
me the commands to run and I'll provide the feedback,

P.P.S. -- Appreciate all you guys do -- my linux video box runs
circles around my Vista Media Center.

Last P.S. - Linux Media Rocks.

-BEGIN PGP SIGNATURE-
Version: GnuPG v2.0.14 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJPvVAmAAoJEKqgpLIhfz3XcFAH/3bViyDt/YxLBbxtHi+fvofY
cHWPBD1ls8QxPSfmumVU8fZR6qcg1RIg9FpbOcngXpnGdOjK0NXJ7oQngX34WCrR
1NJgl4fc1YEBM6QzoOVHXC9Yg6iQnAShru4PIyP4VmuwDNIT/y7HZnB06bGUd6Fv
1qxxKKzfwC4IxlzjX2jl3A+p/ujFJCGe/oIt+Q1JJho1Xq1rMYGEguQGyuPkLgjA
MtfmObGA7OhrFDbdJ9cagW1o3Uu3CXa53qq5QPTGDzw4H6agmjQgL2PVUdgbc2X9
ijB1kFTK9WwP4zbeVKUSejk8Jp1gC6n8ntBtdOe+I+uH6D0ONzznNCur2p+EbcU=
=NL8P
-END PGP SIGNATURE-
--
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] via-camera: pass correct format settings to sensor

2012-05-23 Thread Daniel Drake
The code attempts to maintain a user format and a sensor format,
but in this case it looks like a typo is passing the user format down
to the sensor.

This was preventing display of video at anything other than 640x480.

Signed-off-by: Daniel Drake d...@laptop.org
---
 drivers/media/video/via-camera.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 308e150..eb404c2 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -963,7 +963,7 @@ static int viacam_do_try_fmt(struct via_camera *cam,
 
upix-pixelformat = f-pixelformat;
viacam_fmt_pre(upix, spix);
-   v4l2_fill_mbus_format(mbus_fmt, upix, f-mbus_code);
+   v4l2_fill_mbus_format(mbus_fmt, spix, f-mbus_code);
ret = sensor_call(cam, video, try_mbus_fmt, mbus_fmt);
v4l2_fill_pix_format(spix, mbus_fmt);
viacam_fmt_post(upix, spix);
-- 
1.7.10.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: 3.1/3.2 uvcvideo and Creative Live! Cam Optia AF

2012-05-23 Thread bmullan
Laurent Pinchart laurent.pinchart at ideasonboard.com writes:

 
 Hi Josh,
 
 On Wednesday 29 February 2012 17:58:52 Josh Boyer wrote:
  Hi Laurent,
  
  We've had a bug report [1] in Fedora for a while now that the uvcvideo
  driver no longer works on the Creative Live! Cam Optia AF (ID 041e:4058)
  in the 3.1 and 3.2 kernels.  The bug has all the various output from
  dmesg, lsusb, etc.
  
  I'm wondering if there is anything further we can do to help diagnose
  what might be going wrong here.
  
  josh
  
  [1] https://bugzilla.redhat.com/show_bug.cgi?id=739448
 
 I've asked for more information directly in the bug report.
 

I'm using Ubuntu 12.04 x64, kernel 3.2.0.24
and the Optia AF has the same problem
uvcvideo, cheese etc all show the device and that its using /dev/video0 but
there is no data being received/displayed.



--
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 v3 08/10] arm: omap4panda: Add support for omap4iss camera

2012-05-23 Thread Sergio Aguirre
Hi Tony,

On Tue, May 8, 2012 at 6:46 PM, Tony Lindgren t...@atomide.com wrote:
 * Sergio Aguirre saagui...@ti.com [120502 08:21]:
 This adds support for camera interface with the support for
 following sensors:

 - OV5640
 - OV5650

 It seems that at this point we should initialize new things like this
 with DT only. We don't quite yet have the muxing in place, but I'd
 rather not add yet another big platform_data file for something that
 does not even need to be there for DT booted devices.

Ok.

I'll look at that.

By the way, I've been very out of the loop on al DT related development..

Are these instructions valid for current master k.org branch?

http://omappedia.org/wiki/Device_Tree#Booting_with_DT_blob

Regards,
Sergio


 Regards,

 Tony
 --
 To unsubscribe from this list: send the line unsubscribe linux-omap in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.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