Re: [PATCH 2/2] [media] Input: synaptics-rmi4: disallow impossible configuration

2016-09-15 Thread Nick Dyer
On Mon, Sep 12, 2016 at 05:30:33PM +0200, Arnd Bergmann wrote:
> The newly added debug mode for the synaptics-rmi4 driver relies on
> the v4l2 interface and vb2_vmalloc, but those might be configured
> as loadable modules when the driver itself is built-in, resulting
> in a link failure:
> 
> drivers/input/rmi4/rmi_core.o: In function `rmi_f54_remove':
> rmi_f54.c:(.text.rmi_f54_remove+0x14): undefined reference to 
> `video_unregister_device'
> rmi_f54.c:(.text.rmi_f54_remove+0x20): undefined reference to 
> `v4l2_device_unregister'
> drivers/input/rmi4/rmi_core.o: In function `rmi_f54_vidioc_s_input':
> rmi_f54.c:(.text.rmi_f54_vidioc_s_input+0x10): undefined reference to 
> `video_devdata'
> drivers/input/rmi4/rmi_core.o: In function `rmi_f54_vidioc_g_input':
> rmi_f54.c:(.text.rmi_f54_vidioc_g_input+0x10): undefined reference to 
> `video_devdata'
> drivers/input/rmi4/rmi_core.o: In function `rmi_f54_vidioc_fmt':
> rmi_f54.c:(.text.rmi_f54_vidioc_fmt+0x10): undefined reference to 
> `video_devdata'
> drivers/input/rmi4/rmi_core.o: In function `rmi_f54_vidioc_enum_input':
> rmi_f54.c:(.text.rmi_f54_vidioc_enum_input+0x10): undefined reference to 
> `video_devdata'
> drivers/input/rmi4/rmi_core.o: In function `rmi_f54_vidioc_querycap':
> ...
> 
> The best workaround I could come up with is to disallow the debug
> mode unless it's actually possible to call it.
> 
> Signed-off-by: Arnd Bergmann <a...@arndb.de>
> Fixes: 3a762dbd5347 ("[media] Input: synaptics-rmi4 - add support for F54 
> diagnostics")

Acked-by: Nick Dyer <n...@shmanahar.org>

> ---
>  drivers/input/rmi4/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
> index f3418b65eb41..4c8a55857e00 100644
> --- a/drivers/input/rmi4/Kconfig
> +++ b/drivers/input/rmi4/Kconfig
> @@ -65,7 +65,7 @@ config RMI4_F30
>  config RMI4_F54
>   bool "RMI4 Function 54 (Analog diagnostics)"
>   depends on RMI4_CORE
> - depends on VIDEO_V4L2
> + depends on VIDEO_V4L2=y || (RMI4_CORE=m && VIDEO_V4L2=m)
>   select VIDEOBUF2_VMALLOC
>   help
> Say Y here if you want to add support for RMI4 function 54
> -- 
> 2.9.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


[PATCH] Input: v4l-touch - add copyright lines

2016-09-15 Thread Nick Dyer
Hi Hans-

Please could you apply this patch to your media_tree/touch branch before it
goes to v4.9 if possible.

Thanks



Add copyright lines for Zodiac who paid for the V4L touch work.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/rmi4/rmi_f54.c | 1 +
 drivers/input/touchscreen/atmel_mxt_ts.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c
index 99a8836..185b753 100644
--- a/drivers/input/rmi4/rmi_f54.c
+++ b/drivers/input/rmi4/rmi_f54.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012-2015 Synaptics Incorporated
+ * Copyright (C) 2016 Zodiac Inflight Innovations
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published by
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index beede8f..e5d185f 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2010 Samsung Electronics Co.Ltd
  * Copyright (C) 2011-2014 Atmel Corporation
  * Copyright (C) 2012 Google, Inc.
+ * Copyright (C) 2016 Zodiac Inflight Innovations
  *
  * Author: Joonyoung Shim <jy0922.s...@samsung.com>
  *
-- 
2.7.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


Re: [PATCH 1/2] [media] Input: atmel_mxt: disallow impossible configuration

2016-09-15 Thread Nick Dyer
On Mon, Sep 12, 2016 at 05:30:32PM +0200, Arnd Bergmann wrote:
> The newnly added debug mode for the atmel_mxt_ts driver relies on
> the v4l2 interface and vb2_vmalloc, but those might be configured
> as loadable modules when the driver itself is built-in, resulting
> in a link failure:
> 
> drivers/input/touchscreen/atmel_mxt_ts.o: In function `mxt_vidioc_querycap':
> atmel_mxt_ts.c:(.text.mxt_vidioc_querycap+0x10): undefined reference to 
> `video_devdata'
> drivers/input/touchscreen/atmel_mxt_ts.o: In function `mxt_buffer_queue':
> atmel_mxt_ts.c:(.text.mxt_buffer_queue+0x20): undefined reference to 
> `vb2_plane_vaddr'
> atmel_mxt_ts.c:(.text.mxt_buffer_queue+0x164): undefined reference to 
> `vb2_buffer_done'
> drivers/input/touchscreen/atmel_mxt_ts.o: In function `mxt_free_object_table':
> atmel_mxt_ts.c:(.text.mxt_free_object_table+0x18): undefined reference to 
> `video_unregister_device'
> atmel_mxt_ts.c:(.text.mxt_free_object_table+0x20): undefined reference to 
> `v4l2_device_unregister'
> 
> The best workaround I could come up with is to disallow the debug
> mode unless it's actually possible to call it.
> 
> Signed-off-by: Arnd Bergmann <a...@arndb.de>
> Fixes: ecfdd7e2660e ("[media] Input: atmel_mxt_ts - output diagnostic debug 
> via V4L2 device")

Acked-by: Nick Dyer <n...@shmanahar.org>

> ---
>  drivers/input/touchscreen/Kconfig | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/input/touchscreen/Kconfig 
> b/drivers/input/touchscreen/Kconfig
> index fce1e41ffe8b..ccf933969587 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -117,7 +117,8 @@ config TOUCHSCREEN_ATMEL_MXT
>  
>  config TOUCHSCREEN_ATMEL_MXT_T37
>   bool "Support T37 Diagnostic Data"
> - depends on TOUCHSCREEN_ATMEL_MXT && VIDEO_V4L2
> + depends on TOUCHSCREEN_ATMEL_MXT
> + depends on VIDEO_V4L2=y || (TOUCHSCREEN_ATMEL_MXT=m && VIDEO_V4L2=m)
>   select VIDEOBUF2_VMALLOC
>   help
> Say Y here if you want support to output data from the T37
> -- 
> 2.9.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


[PATCH v2] Documentation: add support for V4L touch devices

2016-08-14 Thread Nick Dyer
[v2: Fix minor issues and document V4L2_INPUT_TYPE_TOUCH and V4L2_CAP_TOUCH]

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 Documentation/media/uapi/mediactl/media-types.rst |  24 +++--
 Documentation/media/uapi/v4l/dev-touch.rst|  56 +++
 Documentation/media/uapi/v4l/devices.rst  |   1 +
 Documentation/media/uapi/v4l/pixfmt-tch-td08.rst  |  80 
 Documentation/media/uapi/v4l/pixfmt-tch-td16.rst  | 111 ++
 Documentation/media/uapi/v4l/pixfmt-tch-tu08.rst  |  78 +++
 Documentation/media/uapi/v4l/pixfmt-tch-tu16.rst  | 110 +
 Documentation/media/uapi/v4l/pixfmt.rst   |   1 +
 Documentation/media/uapi/v4l/tch-formats.rst  |  18 
 Documentation/media/uapi/v4l/vidioc-enuminput.rst |   8 ++
 Documentation/media/uapi/v4l/vidioc-querycap.rst  |   8 ++
 11 files changed, 488 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/media/uapi/v4l/dev-touch.rst
 create mode 100644 Documentation/media/uapi/v4l/pixfmt-tch-td08.rst
 create mode 100644 Documentation/media/uapi/v4l/pixfmt-tch-td16.rst
 create mode 100644 Documentation/media/uapi/v4l/pixfmt-tch-tu08.rst
 create mode 100644 Documentation/media/uapi/v4l/pixfmt-tch-tu16.rst
 create mode 100644 Documentation/media/uapi/v4l/tch-formats.rst

diff --git a/Documentation/media/uapi/mediactl/media-types.rst 
b/Documentation/media/uapi/mediactl/media-types.rst
index c77717b..0265edc 100644
--- a/Documentation/media/uapi/mediactl/media-types.rst
+++ b/Documentation/media/uapi/mediactl/media-types.rst
@@ -429,6 +429,16 @@ Types and flags used to represent the media graph elements
 
 -  .. row 11
 
+   ..  _MEDIA-INTF-T-V4L-TOUCH:
+
+   -  ``MEDIA_INTF_T_V4L_TOUCH``
+
+   -  Device node interface for Touch device (V4L)
+
+   -  typically, /dev/v4l-touch?
+
+-  .. row 12
+
..  _MEDIA-INTF-T-ALSA-PCM-CAPTURE:
 
-  ``MEDIA_INTF_T_ALSA_PCM_CAPTURE``
@@ -437,7 +447,7 @@ Types and flags used to represent the media graph elements
 
-  typically, /dev/snd/pcmC?D?c
 
--  .. row 12
+-  .. row 13
 
..  _MEDIA-INTF-T-ALSA-PCM-PLAYBACK:
 
@@ -447,7 +457,7 @@ Types and flags used to represent the media graph elements
 
-  typically, /dev/snd/pcmC?D?p
 
--  .. row 13
+-  .. row 14
 
..  _MEDIA-INTF-T-ALSA-CONTROL:
 
@@ -457,7 +467,7 @@ Types and flags used to represent the media graph elements
 
-  typically, /dev/snd/controlC?
 
--  .. row 14
+-  .. row 15
 
..  _MEDIA-INTF-T-ALSA-COMPRESS:
 
@@ -467,7 +477,7 @@ Types and flags used to represent the media graph elements
 
-  typically, /dev/snd/compr?
 
--  .. row 15
+-  .. row 16
 
..  _MEDIA-INTF-T-ALSA-RAWMIDI:
 
@@ -477,7 +487,7 @@ Types and flags used to represent the media graph elements
 
-  typically, /dev/snd/midi?
 
--  .. row 16
+-  .. row 17
 
..  _MEDIA-INTF-T-ALSA-HWDEP:
 
@@ -487,7 +497,7 @@ Types and flags used to represent the media graph elements
 
-  typically, /dev/snd/hwC?D?
 
--  .. row 17
+-  .. row 18
 
..  _MEDIA-INTF-T-ALSA-SEQUENCER:
 
@@ -497,7 +507,7 @@ Types and flags used to represent the media graph elements
 
-  typically, /dev/snd/seq
 
--  .. row 18
+-  .. row 19
 
..  _MEDIA-INTF-T-ALSA-TIMER:
 
diff --git a/Documentation/media/uapi/v4l/dev-touch.rst 
b/Documentation/media/uapi/v4l/dev-touch.rst
new file mode 100644
index 000..1f4e752
--- /dev/null
+++ b/Documentation/media/uapi/v4l/dev-touch.rst
@@ -0,0 +1,56 @@
+.. -*- coding: utf-8; mode: rst -*-
+
+.. _touch:
+
+*
+Touch Devices
+*
+
+Touch devices are accessed through character device special files named
+``/dev/v4l-touch0`` to ``/dev/v4l-touch255`` with major number 81 and
+dynamically allocated minor numbers 0 to 255.
+
+Overview
+
+
+Sensors may be Optical, or Projected Capacitive touch (PCT).
+
+Processing is required to analyse the raw data and produce input events. In
+some systems, this may be performed on the ASIC and the raw data is purely a
+side-channel for diagnostics or tuning. In other systems, the ASIC is a simple
+analogue front end device which delivers touch data at high rate, and any touch
+processing must be done on the host.
+
+For capacitive touch sensing, the touchscreen is composed of an array of
+horizontal and vertical conductors (alternatively called rows/columns, X/Y
+lines, or tx/rx). Mutual Capacitance measured is at the nodes where the
+conductors cross. Alternatively, Self Capacitance measures the signal from each
+column and row independently.
+
+A touch input may be determined by comparing the raw capacitance measurement to
+a no-touch reference (or "baseline") measurement:
+
+Delta = Raw - Reference
+
+The reference measurement takes account of variations in the capacitance across
+the touch sensor matrix, for example manufacturin

Re: [PATCH v8 10/10] Input: sur40 - use new V4L2 touch input type

2016-08-12 Thread Nick Dyer
Signed-off-by: Nick Dyer <n...@shmanahar.org>

On 12 August 2016 10:41:08 BST, Hans Verkuil <hverk...@xs4all.nl> wrote:
>Hi Nick,
>
>On 07/18/2016 11:10 PM, Nick Dyer wrote:
>> Support both V4L2_TCH_FMT_TU08 and V4L2_PIX_FMT_GREY for backwards
>> compatibility.
>> 
>> Note: I have not tested these changes (I have no access to the
>hardware)
>> so not signing off.
>
>I can't merge this without your Signed-off. The Signed-off has nothing
>to do with
>whether or not you have tested the code. I'm leaving this out of the
>pull request
>for now.
>
>Regards,
>
>   Hans
>
>> ---
>>  drivers/input/touchscreen/sur40.c |  122
>+++--
>>  1 file changed, 89 insertions(+), 33 deletions(-)
>> 
>> diff --git a/drivers/input/touchscreen/sur40.c
>b/drivers/input/touchscreen/sur40.c
>> index 4ea4757..fc275cb 100644
>> --- a/drivers/input/touchscreen/sur40.c
>> +++ b/drivers/input/touchscreen/sur40.c
>> @@ -139,6 +139,27 @@ struct sur40_image_header {
>>  #define SUR40_GET_STATE   0xc5 /*  4 bytes state (?) */
>>  #define SUR40_GET_SENSORS 0xb1 /*  8 bytes sensors   */
>>  
>> +static const struct v4l2_pix_format sur40_pix_format[] = {
>> +{
>> +.pixelformat = V4L2_TCH_FMT_TU08,
>> +.width  = SENSOR_RES_X / 2,
>> +.height = SENSOR_RES_Y / 2,
>> +.field = V4L2_FIELD_NONE,
>> +.colorspace = V4L2_COLORSPACE_SRGB,
>> +.bytesperline = SENSOR_RES_X / 2,
>> +.sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
>> +},
>> +{
>> +.pixelformat = V4L2_PIX_FMT_GREY,
>> +.width  = SENSOR_RES_X / 2,
>> +.height = SENSOR_RES_Y / 2,
>> +.field = V4L2_FIELD_NONE,
>> +.colorspace = V4L2_COLORSPACE_SRGB,
>> +.bytesperline = SENSOR_RES_X / 2,
>> +.sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
>> +}
>> +};
>> +
>>  /* master device state */
>>  struct sur40_state {
>>  
>> @@ -149,6 +170,7 @@ struct sur40_state {
>>  struct v4l2_device v4l2;
>>  struct video_device vdev;
>>  struct mutex lock;
>> +struct v4l2_pix_format pix_fmt;
>>  
>>  struct vb2_queue queue;
>>  struct list_head buf_list;
>> @@ -169,7 +191,6 @@ struct sur40_buffer {
>>  
>>  /* forward declarations */
>>  static const struct video_device sur40_video_device;
>> -static const struct v4l2_pix_format sur40_video_format;
>>  static const struct vb2_queue sur40_queue;
>>  static void sur40_process_video(struct sur40_state *sur40);
>>  
>> @@ -420,7 +441,7 @@ static void sur40_process_video(struct
>sur40_state *sur40)
>>  goto err_poll;
>>  }
>>  
>> -if (le32_to_cpu(img->size) != sur40_video_format.sizeimage) {
>> +if (le32_to_cpu(img->size) != sur40->pix_fmt.sizeimage) {
>>  dev_err(sur40->dev, "image size mismatch\n");
>>  goto err_poll;
>>  }
>> @@ -431,7 +452,7 @@ static void sur40_process_video(struct
>sur40_state *sur40)
>>  
>>  result = usb_sg_init(, sur40->usbdev,
>>  usb_rcvbulkpipe(sur40->usbdev, VIDEO_ENDPOINT), 0,
>> -sgt->sgl, sgt->nents, sur40_video_format.sizeimage, 0);
>> +sgt->sgl, sgt->nents, sur40->pix_fmt.sizeimage, 0);
>>  if (result < 0) {
>>  dev_err(sur40->dev, "error %d in usb_sg_init\n", result);
>>  goto err_poll;
>> @@ -586,13 +607,14 @@ static int sur40_probe(struct usb_interface
>*interface,
>>  if (error)
>>  goto err_unreg_v4l2;
>>  
>> +sur40->pix_fmt = sur40_pix_format[0];
>>  sur40->vdev = sur40_video_device;
>>  sur40->vdev.v4l2_dev = >v4l2;
>>  sur40->vdev.lock = >lock;
>>  sur40->vdev.queue = >queue;
>>  video_set_drvdata(>vdev, sur40);
>>  
>> -error = video_register_device(>vdev, VFL_TYPE_GRABBER, -1);
>> +error = video_register_device(>vdev, VFL_TYPE_TOUCH, -1);
>>  if (error) {
>>  dev_err(>dev,
>>  "Unable to register video subdevice.");
>> @@ -651,10 +673,10 @@ static int sur40_queue_setup(struct vb2_queue
>*q,
>>  *nbuffers = 3 - q->num_buffers;
>>  
>>  if (*nplanes)
>> -return sizes[0] < sur40_video_format.sizeimage ? -EI

[PATCH v8 10/10] Input: sur40 - use new V4L2 touch input type

2016-07-18 Thread Nick Dyer
Support both V4L2_TCH_FMT_TU08 and V4L2_PIX_FMT_GREY for backwards
compatibility.

Note: I have not tested these changes (I have no access to the hardware)
so not signing off.
---
 drivers/input/touchscreen/sur40.c |  122 +++--
 1 file changed, 89 insertions(+), 33 deletions(-)

diff --git a/drivers/input/touchscreen/sur40.c 
b/drivers/input/touchscreen/sur40.c
index 4ea4757..fc275cb 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -139,6 +139,27 @@ struct sur40_image_header {
 #define SUR40_GET_STATE   0xc5 /*  4 bytes state (?) */
 #define SUR40_GET_SENSORS 0xb1 /*  8 bytes sensors   */
 
+static const struct v4l2_pix_format sur40_pix_format[] = {
+   {
+   .pixelformat = V4L2_TCH_FMT_TU08,
+   .width  = SENSOR_RES_X / 2,
+   .height = SENSOR_RES_Y / 2,
+   .field = V4L2_FIELD_NONE,
+   .colorspace = V4L2_COLORSPACE_SRGB,
+   .bytesperline = SENSOR_RES_X / 2,
+   .sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
+   },
+   {
+   .pixelformat = V4L2_PIX_FMT_GREY,
+   .width  = SENSOR_RES_X / 2,
+   .height = SENSOR_RES_Y / 2,
+   .field = V4L2_FIELD_NONE,
+   .colorspace = V4L2_COLORSPACE_SRGB,
+   .bytesperline = SENSOR_RES_X / 2,
+   .sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
+   }
+};
+
 /* master device state */
 struct sur40_state {
 
@@ -149,6 +170,7 @@ struct sur40_state {
struct v4l2_device v4l2;
struct video_device vdev;
struct mutex lock;
+   struct v4l2_pix_format pix_fmt;
 
struct vb2_queue queue;
struct list_head buf_list;
@@ -169,7 +191,6 @@ struct sur40_buffer {
 
 /* forward declarations */
 static const struct video_device sur40_video_device;
-static const struct v4l2_pix_format sur40_video_format;
 static const struct vb2_queue sur40_queue;
 static void sur40_process_video(struct sur40_state *sur40);
 
@@ -420,7 +441,7 @@ static void sur40_process_video(struct sur40_state *sur40)
goto err_poll;
}
 
-   if (le32_to_cpu(img->size) != sur40_video_format.sizeimage) {
+   if (le32_to_cpu(img->size) != sur40->pix_fmt.sizeimage) {
dev_err(sur40->dev, "image size mismatch\n");
goto err_poll;
}
@@ -431,7 +452,7 @@ static void sur40_process_video(struct sur40_state *sur40)
 
result = usb_sg_init(, sur40->usbdev,
usb_rcvbulkpipe(sur40->usbdev, VIDEO_ENDPOINT), 0,
-   sgt->sgl, sgt->nents, sur40_video_format.sizeimage, 0);
+   sgt->sgl, sgt->nents, sur40->pix_fmt.sizeimage, 0);
if (result < 0) {
dev_err(sur40->dev, "error %d in usb_sg_init\n", result);
goto err_poll;
@@ -586,13 +607,14 @@ static int sur40_probe(struct usb_interface *interface,
if (error)
goto err_unreg_v4l2;
 
+   sur40->pix_fmt = sur40_pix_format[0];
sur40->vdev = sur40_video_device;
sur40->vdev.v4l2_dev = >v4l2;
sur40->vdev.lock = >lock;
sur40->vdev.queue = >queue;
video_set_drvdata(>vdev, sur40);
 
-   error = video_register_device(>vdev, VFL_TYPE_GRABBER, -1);
+   error = video_register_device(>vdev, VFL_TYPE_TOUCH, -1);
if (error) {
dev_err(>dev,
"Unable to register video subdevice.");
@@ -651,10 +673,10 @@ static int sur40_queue_setup(struct vb2_queue *q,
*nbuffers = 3 - q->num_buffers;
 
if (*nplanes)
-   return sizes[0] < sur40_video_format.sizeimage ? -EINVAL : 0;
+   return sizes[0] < sur40->pix_fmt.sizeimage ? -EINVAL : 0;
 
*nplanes = 1;
-   sizes[0] = sur40_video_format.sizeimage;
+   sizes[0] = sur40->pix_fmt.sizeimage;
 
return 0;
 }
@@ -666,7 +688,7 @@ static int sur40_queue_setup(struct vb2_queue *q,
 static int sur40_buffer_prepare(struct vb2_buffer *vb)
 {
struct sur40_state *sur40 = vb2_get_drv_priv(vb->vb2_queue);
-   unsigned long size = sur40_video_format.sizeimage;
+   unsigned long size = sur40->pix_fmt.sizeimage;
 
if (vb2_plane_size(vb, 0) < size) {
dev_err(>usbdev->dev, "buffer too small (%lu < %lu)\n",
@@ -741,7 +763,7 @@ static int sur40_vidioc_querycap(struct file *file, void 
*priv,
strlcpy(cap->driver, DRIVER_SHORT, sizeof(cap->driver));
strlcpy(cap->card, DRIVER_LONG, sizeof(cap->card));
usb_make_path(sur40->usbdev, cap->bus_info, sizeof(cap->bus_info));
-   cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
+   cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TOUCH |
V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING;
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -753,7 +775,7 @@ static int sur40_vidioc_enum_input(struct file *file, 

[PATCH v8 0/10] Output raw touch data via V4L2

2016-07-18 Thread Nick Dyer
This is a series of patches to add output of raw touch diagnostic data via V4L2
to the Atmel maXTouch and Synaptics RMI4 drivers.

It's a rewrite of the previous implementation which output via debugfs: it now
uses a V4L2 device in a similar way to the sur40 driver.

We have a utility which can read the data and display it in a useful format:
https://github.com/ndyer/heatmap/commits/heatmap-v4l

Changes in v8:
- Split out docs changes, rework in RST/Sphinx, and rebase against docs-next
- Update for changes to vb2_queue alloc_ctxs
- Rebase against git://linuxtv.org/media_tree.git and re-test

Changes in v7:
- Tested by Andrew Duggan and Chris Healy.
- Update bus_info to add "rmi4:" bus.
- Fix code style issues in sur40 changes.

Changes in v6:
- Remove BUF_TYPE_TOUCH_CAPTURE, as discussed with Hans V touch devices will
  use BUF_TYPE_VIDEO_CAPTURE.
- Touch devices should now register CAP_VIDEO_CAPTURE: CAP_TOUCH just says that
  this is a touch device, not a video device, but otherwise it acts the same.
- Add some code to v4l_s_fmt() to set sensible default values for fields not
  used by touch.
- Improve naming/doc of RMI4 F54 report types.
- Various minor DocBook fixes, and split to separate patch.
- Update my email address.
- Rework sur40 changes so that PIX_FMT_GREY is supported for backward
  compatibility. Florian is it possible for you to test?

Changes in v5 (Hans Verkuil review):
- Update v4l2-core:
  - Add VFL_TYPE_TOUCH, V4L2_BUF_TYPE_TOUCH_CAPTURE and V4L2_CAP_TOUCH
  - Change V4L2_INPUT_TYPE_TOUCH_SENSOR to V4L2_INPUT_TYPE_TOUCH
  - Improve DocBook documentation
  - Add FMT definitions for touch data
  - Note this will need the latest version of the heatmap util
- Synaptics RMI4 driver:
  - Remove some less important non full frame report types
  - Switch report type names to const char * array
  - Move a static array to inside context struct
- Split sur40 changes to a separate commit

Changes in v4:
- Address nits from the input side in atmel_mxt_ts patches (Dmitry Torokhov)
- Add Synaptics RMI4 F54 support patch

Changes in v3:
- Address V4L2 review comments from Hans Verkuil
- Run v4l-compliance and fix all issues - needs minor patch here:
  https://github.com/ndyer/v4l-utils/commit/cf50469773f

Changes in v2:
- Split pixfmt changes into separate commit and add DocBook
- Introduce VFL_TYPE_TOUCH_SENSOR and /dev/v4l-touch
- Remove "single node" support for now, it may be better to treat it as
  metadata later
- Explicitly set VFL_DIR_RX
- Fix Kconfig

--
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 v8 03/10] Input: atmel_mxt_ts - add support for T37 diagnostic data

2016-07-18 Thread Nick Dyer
Atmel maXTouch devices have a T37 object which can be used to read raw
touch deltas from the device. This consists of an array of 16-bit
integers, one for each node on the touchscreen matrix.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/Kconfig|6 ++
 drivers/input/touchscreen/atmel_mxt_ts.c |  159 ++
 2 files changed, 165 insertions(+)

diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index 8ecdc38..da96ecf 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -115,6 +115,12 @@ config TOUCHSCREEN_ATMEL_MXT
  To compile this driver as a module, choose M here: the
  module will be called atmel_mxt_ts.
 
+config TOUCHSCREEN_ATMEL_MXT_T37
+   bool "Support T37 Diagnostic Data"
+   depends on TOUCHSCREEN_ATMEL_MXT
+   help
+ Say Y here if you want support for the T37 Diagnostic Data object.
+
 config TOUCHSCREEN_AUO_PIXCIR
tristate "AUO in-cell touchscreen using Pixcir ICs"
depends on I2C
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 5af7907..0048233 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -124,6 +124,19 @@ struct t9_range {
 #define MXT_COMMS_CTRL 0
 #define MXT_COMMS_CMD  1
 
+/* MXT_DEBUG_DIAGNOSTIC_T37 */
+#define MXT_DIAGNOSTIC_PAGEUP  0x01
+#define MXT_DIAGNOSTIC_DELTAS  0x10
+#define MXT_DIAGNOSTIC_SIZE128
+
+struct t37_debug {
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+   u8 mode;
+   u8 page;
+   u8 data[MXT_DIAGNOSTIC_SIZE];
+#endif
+};
+
 /* Define for MXT_GEN_COMMAND_T6 */
 #define MXT_BOOT_VALUE 0xa5
 #define MXT_RESET_VALUE0x01
@@ -205,6 +218,14 @@ struct mxt_object {
u8 num_report_ids;
 } __packed;
 
+struct mxt_dbg {
+   u16 t37_address;
+   u16 diag_cmd_address;
+   struct t37_debug *t37_buf;
+   unsigned int t37_pages;
+   unsigned int t37_nodes;
+};
+
 /* Each client has this additional data */
 struct mxt_data {
struct i2c_client *client;
@@ -233,6 +254,7 @@ struct mxt_data {
u8 num_touchids;
u8 multitouch;
struct t7_config t7_cfg;
+   struct mxt_dbg dbg;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -2043,6 +2065,141 @@ recheck:
return 0;
 }
 
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
+  unsigned int y)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int ofs, page;
+
+   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   page = ofs / MXT_DIAGNOSTIC_SIZE;
+   ofs %= MXT_DIAGNOSTIC_SIZE;
+
+   return get_unaligned_le16(>t37_buf[page].data[ofs]);
+}
+
+static int mxt_convert_debug_pages(struct mxt_data *data, u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int x = 0;
+   unsigned int y = 0;
+   unsigned int i;
+
+   for (i = 0; i < dbg->t37_nodes; i++) {
+   outbuf[i] = mxt_get_debug_value(data, x, y);
+
+   /* Next value */
+   if (++x >= data->info.matrix_xsize) {
+   x = 0;
+   y++;
+   }
+   }
+
+   return 0;
+}
+
+static int mxt_read_diagnostic_debug(struct mxt_data *data, u8 mode,
+u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   int retries = 0;
+   int page;
+   int ret;
+   u8 cmd = mode;
+   struct t37_debug *p;
+   u8 cmd_poll;
+
+   for (page = 0; page < dbg->t37_pages; page++) {
+   p = dbg->t37_buf + page;
+
+   ret = mxt_write_reg(data->client, dbg->diag_cmd_address,
+   cmd);
+   if (ret)
+   return ret;
+
+   retries = 0;
+   msleep(20);
+wait_cmd:
+   /* Read back command byte */
+   ret = __mxt_read_reg(data->client, dbg->diag_cmd_address,
+sizeof(cmd_poll), _poll);
+   if (ret)
+   return ret;
+
+   /* Field is cleared once the command has been processed */
+   if (cmd_poll) {
+   if (retries++ > 100)
+   return -EINVAL;
+
+   msleep(20);
+   goto wait_cmd;
+   }
+
+   /* Read T37 page */
+   ret = __mxt_read_reg(data->client, dbg->t37_address,
+sizeof(struct t37_debug), p);
+   if (ret)
+   return ret;
+
+   if (p->mode != mode || p->page != page) {
+  

[PATCH] v4l2-compliance: Changes to support touch sensors

2016-07-18 Thread Nick Dyer
Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 utils/v4l2-compliance/v4l2-compliance.cpp|   51 +-
 utils/v4l2-compliance/v4l2-compliance.h  |1 +
 utils/v4l2-compliance/v4l2-test-input-output.cpp |4 +-
 3 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp 
b/utils/v4l2-compliance/v4l2-compliance.cpp
index 48dc8b4..ca2eec7 100644
--- a/utils/v4l2-compliance/v4l2-compliance.cpp
+++ b/utils/v4l2-compliance/v4l2-compliance.cpp
@@ -55,6 +55,7 @@ enum Option {
OptSetRadioDevice = 'r',
OptStreaming = 's',
OptSetSWRadioDevice = 'S',
+   OptSetTouchDevice = 't',
OptTrace = 'T',
OptVerbose = 'v',
OptSetVbiDevice = 'V',
@@ -105,6 +106,7 @@ static struct option long_options[] = {
{"vbi-device", required_argument, 0, OptSetVbiDevice},
{"sdr-device", required_argument, 0, OptSetSWRadioDevice},
{"expbuf-device", required_argument, 0, OptSetExpBufDevice},
+   {"touch-device", required_argument, 0, OptSetTouchDevice},
{"help", no_argument, 0, OptHelp},
{"verbose", no_argument, 0, OptVerbose},
{"no-warnings", no_argument, 0, OptNoWarnings},
@@ -134,6 +136,9 @@ static void usage(void)
printf("  -S, --sdr-device=\n");
printf(" Use device  as the SDR device.\n");
printf(" If  starts with a digit, then 
/dev/swradio is used.\n");
+   printf("  -t, --touch-device=\n");
+   printf(" Use device  as the touch device.\n");
+   printf(" If  starts with a digit, then 
/dev/v4l-touch is used.\n");
printf("  -e, --expbuf-device=\n");
printf(" Use device  to obtain DMABUF 
handles.\n");
printf(" If  starts with a digit, then 
/dev/video is used.\n");
@@ -206,6 +211,8 @@ std::string cap2s(unsigned cap)
s += "\t\tSDR Capture\n";
if (cap & V4L2_CAP_SDR_OUTPUT)
s += "\t\tSDR Output\n";
+   if (cap & V4L2_CAP_TOUCH)
+   s += "\t\tTouch Capture\n";
if (cap & V4L2_CAP_TUNER)
s += "\t\tTuner\n";
if (cap & V4L2_CAP_HW_FREQ_SEEK)
@@ -533,7 +540,8 @@ static int testCap(struct node *node)
memcmp(vcap.bus_info, "ISA:", 4) &&
memcmp(vcap.bus_info, "I2C:", 4) &&
memcmp(vcap.bus_info, "parport", 7) &&
-   memcmp(vcap.bus_info, "platform:", 9))
+   memcmp(vcap.bus_info, "platform:", 9) &&
+   memcmp(vcap.bus_info, "rmi4:", 5))
return fail("missing bus_info prefix ('%s')\n", vcap.bus_info);
fail_on_test((vcap.version >> 16) < 3);
fail_on_test(check_0(vcap.reserved, sizeof(vcap.reserved)));
@@ -673,6 +681,8 @@ int main(int argc, char **argv)
struct node radio_node2;
struct node sdr_node;
struct node sdr_node2;
+   struct node touch_node;
+   struct node touch_node2;
struct node expbuf_node;
 
/* command args */
@@ -682,6 +692,7 @@ int main(int argc, char **argv)
const char *vbi_device = NULL;  /* -V device */
const char *radio_device = NULL;/* -r device */
const char *sdr_device = NULL;  /* -S device */
+   const char *touch_device = NULL;/* -t device */
const char *expbuf_device = NULL;   /* --expbuf-device device */
struct v4l2_capability vcap;/* list_cap */
unsigned frame_count = 60;
@@ -750,6 +761,15 @@ int main(int argc, char **argv)
sdr_device = newdev;
}
break;
+   case OptSetTouchDevice:
+   touch_device = optarg;
+   if (touch_device[0] >= '0' && touch_device[0] <= '9' && 
strlen(touch_device) <= 3) {
+   static char newdev[20];
+
+   sprintf(newdev, "/dev/v4l-touch%s", 
touch_device);
+   touch_device = newdev;
+   }
+   break;
case OptSetExpBufDevice:
expbuf_device = optarg;
if (expbuf_device[0] >= '0' && expbuf_device[0] <= '9' 
&& strlen(expbuf_device) <= 3) {
@@ -839,7 +859,8 @@ int main(int argc, char **argv)
if (v1 == 2 && v2 == 6)
kernel_version = v3;
 
-   if (!video_device && !vbi_device &

[PATCH v8 01/10] Input: atmel_mxt_ts - update MAINTAINERS email address

2016-07-18 Thread Nick Dyer
I'm leaving ITDev, so change to my personal email. My understanding is
that someone at Atmel will take this on once their takeover by Microchip
has settled down.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 MAINTAINERS |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index a15d945..9be2570 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2188,9 +2188,9 @@ S:Maintained
 F: drivers/net/wireless/atmel/atmel*
 
 ATMEL MAXTOUCH DRIVER
-M:     Nick Dyer <nick.d...@itdev.co.uk>
-T: git git://github.com/atmel-maxtouch/linux.git
-S: Supported
+M:     Nick Dyer <n...@shmanahar.org>
+T: git git://github.com/ndyer/linux.git
+S: Maintained
 F: Documentation/devicetree/bindings/input/atmel,maxtouch.txt
 F: drivers/input/touchscreen/atmel_mxt_ts.c
 F: include/linux/platform_data/atmel_mxt_ts.h
-- 
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 v8 04/10] Input: atmel_mxt_ts - output diagnostic debug via V4L2 device

2016-07-18 Thread Nick Dyer
Register a video device to output T37 diagnostic data.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/Kconfig|6 +-
 drivers/input/touchscreen/atmel_mxt_ts.c |  245 ++
 2 files changed, 249 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index da96ecf..7c1c5ec 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -117,9 +117,11 @@ config TOUCHSCREEN_ATMEL_MXT
 
 config TOUCHSCREEN_ATMEL_MXT_T37
bool "Support T37 Diagnostic Data"
-   depends on TOUCHSCREEN_ATMEL_MXT
+   depends on TOUCHSCREEN_ATMEL_MXT && VIDEO_V4L2
+   select VIDEOBUF2_VMALLOC
help
- Say Y here if you want support for the T37 Diagnostic Data object.
+ Say Y here if you want support to output data from the T37
+ Diagnostic Data object using a V4L device.
 
 config TOUCHSCREEN_AUO_PIXCIR
tristate "AUO in-cell touchscreen using Pixcir ICs"
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 0048233..a9f987b 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -28,6 +28,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 /* Firmware files */
 #define MXT_FW_NAME"maxtouch.fw"
@@ -224,6 +228,23 @@ struct mxt_dbg {
struct t37_debug *t37_buf;
unsigned int t37_pages;
unsigned int t37_nodes;
+
+   struct v4l2_device v4l2;
+   struct v4l2_pix_format format;
+   struct video_device vdev;
+   struct vb2_queue queue;
+   struct mutex lock;
+   int input;
+};
+
+static const struct v4l2_file_operations mxt_video_fops = {
+   .owner = THIS_MODULE,
+   .open = v4l2_fh_open,
+   .release = vb2_fop_release,
+   .unlocked_ioctl = video_ioctl2,
+   .read = vb2_fop_read,
+   .mmap = vb2_fop_mmap,
+   .poll = vb2_fop_poll,
 };
 
 /* Each client has this additional data */
@@ -279,6 +300,11 @@ struct mxt_data {
struct completion crc_completion;
 };
 
+struct mxt_vb2_buffer {
+   struct vb2_buffer   vb;
+   struct list_headlist;
+};
+
 static size_t mxt_obj_size(const struct mxt_object *obj)
 {
return obj->size_minus_one + 1;
@@ -1525,6 +1551,11 @@ static void mxt_free_input_device(struct mxt_data *data)
 
 static void mxt_free_object_table(struct mxt_data *data)
 {
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+   video_unregister_device(>dbg.vdev);
+   v4l2_device_unregister(>dbg.v4l2);
+#endif
+
kfree(data->object_table);
data->object_table = NULL;
kfree(data->msg_buf);
@@ -2157,10 +2188,191 @@ wait_cmd:
return mxt_convert_debug_pages(data, outbuf);
 }
 
+static int mxt_queue_setup(struct vb2_queue *q,
+  unsigned int *nbuffers, unsigned int *nplanes,
+  unsigned int sizes[], struct device *alloc_devs[])
+{
+   struct mxt_data *data = q->drv_priv;
+   size_t size = data->dbg.t37_nodes * sizeof(u16);
+
+   if (*nplanes)
+   return sizes[0] < size ? -EINVAL : 0;
+
+   *nplanes = 1;
+   sizes[0] = size;
+
+   return 0;
+}
+
+static void mxt_buffer_queue(struct vb2_buffer *vb)
+{
+   struct mxt_data *data = vb2_get_drv_priv(vb->vb2_queue);
+   u16 *ptr;
+   int ret;
+
+   ptr = vb2_plane_vaddr(vb, 0);
+   if (!ptr) {
+   dev_err(>client->dev, "Error acquiring frame ptr\n");
+   goto fault;
+   }
+
+   ret = mxt_read_diagnostic_debug(data, MXT_DIAGNOSTIC_DELTAS, ptr);
+   if (ret)
+   goto fault;
+
+   vb2_set_plane_payload(vb, 0, data->dbg.t37_nodes * sizeof(u16));
+   vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+   return;
+
+fault:
+   vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+}
+
+/* V4L2 structures */
+static const struct vb2_ops mxt_queue_ops = {
+   .queue_setup= mxt_queue_setup,
+   .buf_queue  = mxt_buffer_queue,
+   .wait_prepare   = vb2_ops_wait_prepare,
+   .wait_finish= vb2_ops_wait_finish,
+};
+
+static const struct vb2_queue mxt_queue = {
+   .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+   .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ,
+   .buf_struct_size = sizeof(struct mxt_vb2_buffer),
+   .ops = _queue_ops,
+   .mem_ops = _vmalloc_memops,
+   .timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC,
+   .min_buffers_needed = 1,
+};
+
+static int mxt_vidioc_querycap(struct file *file, void *priv,
+struct v4l2_capability *cap)
+{
+   struct mxt_data *data = video_drvdata(file);
+
+   strlcpy(cap->driver, "atmel_mxt_ts", sizeof(cap->driver))

[PATCH v8 06/10] Input: atmel_mxt_ts - handle diagnostic data orientation

2016-07-18 Thread Nick Dyer
Invert the diagnostic data to match the orientation of the input device.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/atmel_mxt_ts.c |   26 +-
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 29be261..7376c42 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -125,6 +125,8 @@ struct t9_range {
 
 /* MXT_TOUCH_MULTI_T9 orient */
 #define MXT_T9_ORIENT_SWITCH   (1 << 0)
+#define MXT_T9_ORIENT_INVERTX  (1 << 1)
+#define MXT_T9_ORIENT_INVERTY  (1 << 2)
 
 /* MXT_SPT_COMMSCONFIG_T18 */
 #define MXT_COMMS_CTRL 0
@@ -158,6 +160,8 @@ struct t37_debug {
 #define MXT_T100_YRANGE24
 
 #define MXT_T100_CFG_SWITCHXY  BIT(5)
+#define MXT_T100_CFG_INVERTY   BIT(6)
+#define MXT_T100_CFG_INVERTX   BIT(7)
 
 #define MXT_T100_TCHAUX_VECT   BIT(0)
 #define MXT_T100_TCHAUX_AMPL   BIT(1)
@@ -262,6 +266,8 @@ struct mxt_data {
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
+   bool invertx;
+   bool inverty;
bool xy_switch;
u8 xsize;
u8 ysize;
@@ -1747,6 +1753,8 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return error;
 
data->xy_switch = orient & MXT_T9_ORIENT_SWITCH;
+   data->invertx = orient & MXT_T9_ORIENT_INVERTX;
+   data->inverty = orient & MXT_T9_ORIENT_INVERTY;
 
return 0;
 }
@@ -1801,6 +1809,8 @@ static int mxt_read_t100_config(struct mxt_data *data)
return error;
 
data->xy_switch = cfg & MXT_T100_CFG_SWITCHXY;
+   data->invertx = cfg & MXT_T100_CFG_INVERTX;
+   data->inverty = cfg & MXT_T100_CFG_INVERTY;
 
/* allocate aux bytes */
error =  __mxt_read_reg(client,
@@ -2145,13 +2155,19 @@ static int mxt_convert_debug_pages(struct mxt_data 
*data, u16 *outbuf)
struct mxt_dbg *dbg = >dbg;
unsigned int x = 0;
unsigned int y = 0;
-   unsigned int i;
+   unsigned int i, rx, ry;
 
for (i = 0; i < dbg->t37_nodes; i++) {
-   outbuf[i] = mxt_get_debug_value(data, x, y);
+   /* Handle orientation */
+   rx = data->xy_switch ? y : x;
+   ry = data->xy_switch ? x : y;
+   rx = data->invertx ? (data->xsize - 1 - rx) : rx;
+   ry = data->inverty ? (data->ysize - 1 - ry) : ry;
+
+   outbuf[i] = mxt_get_debug_value(data, rx, ry);
 
/* Next value */
-   if (++x >= data->xsize) {
+   if (++x >= (data->xy_switch ? data->ysize : data->xsize)) {
x = 0;
y++;
}
@@ -2306,8 +2322,8 @@ static int mxt_set_input(struct mxt_data *data, unsigned 
int i)
if (i > 0)
return -EINVAL;
 
-   f->width = data->xsize;
-   f->height = data->ysize;
+   f->width = data->xy_switch ? data->ysize : data->xsize;
+   f->height = data->xy_switch ? data->xsize : data->ysize;
f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
-- 
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 v8 05/10] Input: atmel_mxt_ts - read touchscreen size

2016-07-18 Thread Nick Dyer
The touchscreen may have a margin where not all the matrix is used. Read
the parameters from T9 and T100 and take account of the difference.

Note: this does not read the XORIGIN/YORIGIN fields so it assumes that
the touchscreen starts at (0,0)

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/atmel_mxt_ts.c |   42 +-
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index a9f987b..29be261 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -103,6 +103,8 @@ struct t7_config {
 
 /* MXT_TOUCH_MULTI_T9 field */
 #define MXT_T9_CTRL0
+#define MXT_T9_XSIZE   3
+#define MXT_T9_YSIZE   4
 #define MXT_T9_ORIENT  9
 #define MXT_T9_RANGE   18
 
@@ -150,7 +152,9 @@ struct t37_debug {
 #define MXT_T100_CTRL  0
 #define MXT_T100_CFG1  1
 #define MXT_T100_TCHAUX3
+#define MXT_T100_XSIZE 9
 #define MXT_T100_XRANGE13
+#define MXT_T100_YSIZE 20
 #define MXT_T100_YRANGE24
 
 #define MXT_T100_CFG_SWITCHXY  BIT(5)
@@ -259,6 +263,8 @@ struct mxt_data {
unsigned int max_x;
unsigned int max_y;
bool xy_switch;
+   u8 xsize;
+   u8 ysize;
bool in_bootloader;
u16 mem_size;
u8 t100_aux_ampl;
@@ -1714,6 +1720,18 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return -EINVAL;
 
error = __mxt_read_reg(client,
+  object->start_address + MXT_T9_XSIZE,
+  sizeof(data->xsize), >xsize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T9_YSIZE,
+  sizeof(data->ysize), >ysize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
   object->start_address + MXT_T9_RANGE,
   sizeof(range), );
if (error)
@@ -1763,6 +1781,18 @@ static int mxt_read_t100_config(struct mxt_data *data)
 
data->max_y = get_unaligned_le16(_y);
 
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T100_XSIZE,
+  sizeof(data->xsize), >xsize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T100_YSIZE,
+  sizeof(data->ysize), >ysize);
+   if (error)
+   return error;
+
/* read orientation config */
error =  __mxt_read_reg(client,
object->start_address + MXT_T100_CFG1,
@@ -2121,7 +2151,7 @@ static int mxt_convert_debug_pages(struct mxt_data *data, 
u16 *outbuf)
outbuf[i] = mxt_get_debug_value(data, x, y);
 
/* Next value */
-   if (++x >= data->info.matrix_xsize) {
+   if (++x >= data->xsize) {
x = 0;
y++;
}
@@ -2276,8 +2306,8 @@ static int mxt_set_input(struct mxt_data *data, unsigned 
int i)
if (i > 0)
return -EINVAL;
 
-   f->width = data->info.matrix_xsize;
-   f->height = data->info.matrix_ysize;
+   f->width = data->xsize;
+   f->height = data->ysize;
f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
@@ -2392,9 +2422,9 @@ static void mxt_debug_init(struct mxt_data *data)
dbg->t37_address = object->start_address;
 
/* Calculate size of data and allocate buffer */
-   dbg->t37_nodes = data->info.matrix_xsize * data->info.matrix_ysize;
-   dbg->t37_pages = DIV_ROUND_UP(dbg->t37_nodes * sizeof(u16),
- sizeof(dbg->t37_buf->data));
+   dbg->t37_nodes = data->xsize * data->ysize;
+   dbg->t37_pages = DIV_ROUND_UP(data->xsize * data->info.matrix_ysize *
+ sizeof(u16), sizeof(dbg->t37_buf->data));
 
dbg->t37_buf = devm_kmalloc_array(>client->dev, dbg->t37_pages,
  sizeof(struct t37_debug), GFP_KERNEL);
-- 
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 v8 02/10] v4l2-core: Add support for touch devices

2016-07-18 Thread Nick Dyer
Some touch controllers send out touch data in a similar way to a
greyscale frame grabber.

Add new device type VFL_TYPE_TOUCH:
- This uses a new device prefix v4l-touch for these devices, to stop
  generic capture software from treating them as webcams. Otherwise,
  touch is treated similarly to video capture.
- Add V4L2_INPUT_TYPE_TOUCH
- Add MEDIA_INTF_T_V4L_TOUCH
- Add V4L2_CAP_TOUCH to indicate device is a touch device

Add formats:
- V4L2_TCH_FMT_DELTA_TD16 for signed 16-bit touch deltas
- V4L2_TCH_FMT_DELTA_TD08 for signed 16-bit touch deltas
- V4L2_TCH_FMT_TU16 for unsigned 16-bit touch data
- V4L2_TCH_FMT_TU08 for unsigned 8-bit touch data

This support will be used by:
- Atmel maXTouch (atmel_mxt_ts)
- Synaptics RMI4.
- sur40

Signed-off-by: Nick Dyer <n...@shmanahar.org>
Tested-By: Chris Healy <cphe...@gmail.com>
---
 drivers/media/media-entity.c |2 ++
 drivers/media/v4l2-core/v4l2-dev.c   |   16 ---
 drivers/media/v4l2-core/v4l2-ioctl.c |   36 +-
 include/media/v4l2-dev.h |3 ++-
 include/uapi/linux/media.h   |1 +
 include/uapi/linux/videodev2.h   |9 +
 6 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index d8a2299..9014362 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -65,6 +65,8 @@ static inline const char *intf_type(struct media_interface 
*intf)
return "v4l-subdev";
case MEDIA_INTF_T_V4L_SWRADIO:
return "v4l-swradio";
+   case MEDIA_INTF_T_V4L_TOUCH:
+   return "v4l-touch";
case MEDIA_INTF_T_ALSA_PCM_CAPTURE:
return "alsa-pcm-capture";
case MEDIA_INTF_T_ALSA_PCM_PLAYBACK:
diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index 70b559d..21ba9b4 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -527,6 +527,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI;
bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO;
bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR;
+   bool is_tch = vdev->vfl_type == VFL_TYPE_TOUCH;
bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
 
@@ -573,7 +574,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
if (ops->vidioc_enum_freq_bands || ops->vidioc_g_tuner || 
ops->vidioc_g_modulator)
set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls);
 
-   if (is_vid) {
+   if (is_vid || is_tch) {
/* video specific ioctls */
if ((is_rx && (ops->vidioc_enum_fmt_vid_cap ||
   ops->vidioc_enum_fmt_vid_cap_mplane ||
@@ -662,7 +663,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
}
 
-   if (is_vid || is_vbi || is_sdr) {
+   if (is_vid || is_vbi || is_sdr || is_tch) {
/* ioctls valid for video, vbi or sdr */
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
@@ -675,7 +676,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
}
 
-   if (is_vid || is_vbi) {
+   if (is_vid || is_vbi || is_tch) {
/* ioctls valid for video or vbi */
if (ops->vidioc_s_std)
set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
@@ -751,6 +752,10 @@ static int video_register_media_controller(struct 
video_device *vdev, int type)
intf_type = MEDIA_INTF_T_V4L_SWRADIO;
vdev->entity.function = MEDIA_ENT_F_IO_SWRADIO;
break;
+   case VFL_TYPE_TOUCH:
+   intf_type = MEDIA_INTF_T_V4L_TOUCH;
+   vdev->entity.function = MEDIA_ENT_F_IO_V4L;
+   break;
case VFL_TYPE_RADIO:
intf_type = MEDIA_INTF_T_V4L_RADIO;
/*
@@ -845,6 +850,8 @@ static int video_register_media_controller(struct 
video_device *vdev, int type)
  * %VFL_TYPE_SUBDEV - A subdevice
  *
  * %VFL_TYPE_SDR - Software Defined Radio
+ *
+ * %VFL_TYPE_TOUCH - A touch sensor
  */
 int __video_register_device(struct video_device *vdev, int type, int nr,
int warn_if_nr_in_use, struct module *owner)
@@ -888,6 +895,9 @@ int __video_register_device(struct video_device *vdev, int 
type, int nr,
/* Use device name 'swradio' because 'sdr' was already taken. */
name_base = "swradio";
bre

[PATCH v8 09/10] Input: synaptics-rmi4 - add support for F54 diagnostics

2016-07-18 Thread Nick Dyer
Function 54 implements access to various RMI4 diagnostic features.

This patch adds support for retrieving this data. It registers a V4L2
device to output the data to user space.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
Tested-by: Andrew Duggan <adug...@synaptics.com>
Tested-by: Chris Healy <cphe...@gmail.com>
---
 drivers/input/rmi4/Kconfig  |   11 +
 drivers/input/rmi4/Makefile |1 +
 drivers/input/rmi4/rmi_bus.c|3 +
 drivers/input/rmi4/rmi_driver.h |1 +
 drivers/input/rmi4/rmi_f54.c|  756 +++
 5 files changed, 772 insertions(+)
 create mode 100644 drivers/input/rmi4/rmi_f54.c

diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
index f73df24..f3418b6 100644
--- a/drivers/input/rmi4/Kconfig
+++ b/drivers/input/rmi4/Kconfig
@@ -61,3 +61,14 @@ config RMI4_F30
 
  Function 30 provides GPIO and LED support for RMI4 devices. This
  includes support for buttons on TouchPads and ClickPads.
+
+config RMI4_F54
+   bool "RMI4 Function 54 (Analog diagnostics)"
+   depends on RMI4_CORE
+   depends on VIDEO_V4L2
+   select VIDEOBUF2_VMALLOC
+   help
+ Say Y here if you want to add support for RMI4 function 54
+
+ Function 54 provides access to various diagnostic features in certain
+ RMI4 touch sensors.
diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index 95c00a7..0bafc85 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -7,6 +7,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
+rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 
 # Transports
 obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o
diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index b368b05..3aedc65 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -315,6 +315,9 @@ static struct rmi_function_handler *fn_handlers[] = {
 #ifdef CONFIG_RMI4_F30
_f30_handler,
 #endif
+#ifdef CONFIG_RMI4_F54
+   _f54_handler,
+#endif
 };
 
 static void __rmi_unregister_function_handlers(int start_idx)
diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
index 6e140fa..8dfbebe 100644
--- a/drivers/input/rmi4/rmi_driver.h
+++ b/drivers/input/rmi4/rmi_driver.h
@@ -102,4 +102,5 @@ extern struct rmi_function_handler rmi_f01_handler;
 extern struct rmi_function_handler rmi_f11_handler;
 extern struct rmi_function_handler rmi_f12_handler;
 extern struct rmi_function_handler rmi_f30_handler;
+extern struct rmi_function_handler rmi_f54_handler;
 #endif
diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c
new file mode 100644
index 000..bd86d3d
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f54.c
@@ -0,0 +1,756 @@
+/*
+ * Copyright (c) 2012-2015 Synaptics Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "rmi_driver.h"
+
+#define F54_NAME   "rmi4_f54"
+
+/* F54 data offsets */
+#define F54_REPORT_DATA_OFFSET  3
+#define F54_FIFO_OFFSET 1
+#define F54_NUM_TX_OFFSET   1
+#define F54_NUM_RX_OFFSET   0
+
+/* F54 commands */
+#define F54_GET_REPORT  1
+#define F54_FORCE_CAL   2
+
+/* Fixed sizes of reports */
+#define F54_QUERY_LEN  27
+
+/* F54 capabilities */
+#define F54_CAP_BASELINE   (1 << 2)
+#define F54_CAP_IMAGE8 (1 << 3)
+#define F54_CAP_IMAGE16(1 << 6)
+
+/**
+ * enum rmi_f54_report_type - RMI4 F54 report types
+ *
+ * @F54_8BIT_IMAGE:Normalized 8-Bit Image Report. The capacitance variance
+ * from baseline for each pixel.
+ *
+ * @F54_16BIT_IMAGE:   Normalized 16-Bit Image Report. The capacitance variance
+ * from baseline for each pixel.
+ *
+ * @F54_RAW_16BIT_IMAGE:
+ * Raw 16-Bit Image Report. The raw capacitance for each
+ * pixel.
+ *
+ * @F54_TRUE_BASELINE: True Baseline Report. The baseline capacitance for each
+ * pixel.
+ *
+ * @F54_FULL_RAW_CAP:   Full Raw Capacitance Report. The raw capacitance with
+ * low reference set to its minimum value and high
+ * reference set to its maximum value.
+ *
+ * @F54_FULL_RAW_CAP_RX_OFFSET_REMOVED:
+ * Full Raw Capacitance with Receiver Offset Removed
+ * Report. Set Low reference to its minimum value and high
+ * references to its maximum value, then report the raw
+ * 

[PATCH v8 08/10] Input: atmel_mxt_ts - add support for reference data

2016-07-18 Thread Nick Dyer
There are different datatypes available from a maXTouch chip. Add
support to retrieve reference data as well.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/atmel_mxt_ts.c |   57 ++
 1 file changed, 51 insertions(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 584198e..beede8f 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -135,6 +135,7 @@ struct t9_range {
 /* MXT_DEBUG_DIAGNOSTIC_T37 */
 #define MXT_DIAGNOSTIC_PAGEUP  0x01
 #define MXT_DIAGNOSTIC_DELTAS  0x10
+#define MXT_DIAGNOSTIC_REFS0x11
 #define MXT_DIAGNOSTIC_SIZE128
 
 #define MXT_FAMILY_1386160
@@ -249,6 +250,12 @@ struct mxt_dbg {
int input;
 };
 
+enum v4l_dbg_inputs {
+   MXT_V4L_INPUT_DELTAS,
+   MXT_V4L_INPUT_REFS,
+   MXT_V4L_INPUT_MAX,
+};
+
 static const struct v4l2_file_operations mxt_video_fops = {
.owner = THIS_MODULE,
.open = v4l2_fh_open,
@@ -2273,6 +2280,7 @@ static void mxt_buffer_queue(struct vb2_buffer *vb)
struct mxt_data *data = vb2_get_drv_priv(vb->vb2_queue);
u16 *ptr;
int ret;
+   u8 mode;
 
ptr = vb2_plane_vaddr(vb, 0);
if (!ptr) {
@@ -2280,7 +2288,18 @@ static void mxt_buffer_queue(struct vb2_buffer *vb)
goto fault;
}
 
-   ret = mxt_read_diagnostic_debug(data, MXT_DIAGNOSTIC_DELTAS, ptr);
+   switch (data->dbg.input) {
+   case MXT_V4L_INPUT_DELTAS:
+   default:
+   mode = MXT_DIAGNOSTIC_DELTAS;
+   break;
+
+   case MXT_V4L_INPUT_REFS:
+   mode = MXT_DIAGNOSTIC_REFS;
+   break;
+   }
+
+   ret = mxt_read_diagnostic_debug(data, mode, ptr);
if (ret)
goto fault;
 
@@ -2325,11 +2344,21 @@ static int mxt_vidioc_querycap(struct file *file, void 
*priv,
 static int mxt_vidioc_enum_input(struct file *file, void *priv,
   struct v4l2_input *i)
 {
-   if (i->index > 0)
+   if (i->index >= MXT_V4L_INPUT_MAX)
return -EINVAL;
 
i->type = V4L2_INPUT_TYPE_TOUCH;
-   strlcpy(i->name, "Mutual Capacitance Deltas", sizeof(i->name));
+
+   switch (i->index) {
+   case MXT_V4L_INPUT_REFS:
+   strlcpy(i->name, "Mutual Capacitance References",
+   sizeof(i->name));
+   break;
+   case MXT_V4L_INPUT_DELTAS:
+   strlcpy(i->name, "Mutual Capacitance Deltas", sizeof(i->name));
+   break;
+   }
+
return 0;
 }
 
@@ -2337,12 +2366,16 @@ static int mxt_set_input(struct mxt_data *data, 
unsigned int i)
 {
struct v4l2_pix_format *f = >dbg.format;
 
-   if (i > 0)
+   if (i >= MXT_V4L_INPUT_MAX)
return -EINVAL;
 
+   if (i == MXT_V4L_INPUT_DELTAS)
+   f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
+   else
+   f->pixelformat = V4L2_TCH_FMT_TU16;
+
f->width = data->xy_switch ? data->ysize : data->xsize;
f->height = data->xy_switch ? data->xsize : data->ysize;
-   f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
f->bytesperline = f->width * sizeof(u16);
@@ -2383,7 +2416,19 @@ static int mxt_vidioc_enum_fmt(struct file *file, void 
*priv,
if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
 
-   fmt->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
+   switch (fmt->index) {
+   case 0:
+   fmt->pixelformat = V4L2_TCH_FMT_TU16;
+   break;
+
+   case 1:
+   fmt->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
+   break;
+
+   default:
+   return -EINVAL;
+   }
+
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 v8 07/10] Input: atmel_mxt_ts - add diagnostic data support for mXT1386

2016-07-18 Thread Nick Dyer
The mXT1386 family of chips have a different architecture which splits
the diagnostic data into 3 columns.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/atmel_mxt_ts.c |   31 +++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 7376c42..584198e 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -137,6 +137,10 @@ struct t9_range {
 #define MXT_DIAGNOSTIC_DELTAS  0x10
 #define MXT_DIAGNOSTIC_SIZE128
 
+#define MXT_FAMILY_1386160
+#define MXT1386_COLUMNS3
+#define MXT1386_PAGES_PER_COLUMN   8
+
 struct t37_debug {
 #ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
u8 mode;
@@ -2140,13 +2144,27 @@ recheck:
 static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
   unsigned int y)
 {
+   struct mxt_info *info = >info;
struct mxt_dbg *dbg = >dbg;
unsigned int ofs, page;
+   unsigned int col = 0;
+   unsigned int col_width;
+
+   if (info->family_id == MXT_FAMILY_1386) {
+   col_width = info->matrix_ysize / MXT1386_COLUMNS;
+   col = y / col_width;
+   y = y % col_width;
+   } else {
+   col_width = info->matrix_ysize;
+   }
 
-   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   ofs = (y + (x * col_width)) * sizeof(u16);
page = ofs / MXT_DIAGNOSTIC_SIZE;
ofs %= MXT_DIAGNOSTIC_SIZE;
 
+   if (info->family_id == MXT_FAMILY_1386)
+   page += col * MXT1386_PAGES_PER_COLUMN;
+
return get_unaligned_le16(>t37_buf[page].data[ofs]);
 }
 
@@ -2416,6 +2434,7 @@ static const struct video_device mxt_video_device = {
 
 static void mxt_debug_init(struct mxt_data *data)
 {
+   struct mxt_info *info = >info;
struct mxt_dbg *dbg = >dbg;
struct mxt_object *object;
int error;
@@ -2439,8 +2458,14 @@ static void mxt_debug_init(struct mxt_data *data)
 
/* Calculate size of data and allocate buffer */
dbg->t37_nodes = data->xsize * data->ysize;
-   dbg->t37_pages = DIV_ROUND_UP(data->xsize * data->info.matrix_ysize *
- sizeof(u16), sizeof(dbg->t37_buf->data));
+
+   if (info->family_id == MXT_FAMILY_1386)
+   dbg->t37_pages = MXT1386_COLUMNS * MXT1386_PAGES_PER_COLUMN;
+   else
+   dbg->t37_pages = DIV_ROUND_UP(data->xsize *
+ data->info.matrix_ysize *
+ sizeof(u16),
+ sizeof(dbg->t37_buf->data));
 
dbg->t37_buf = devm_kmalloc_array(>client->dev, dbg->t37_pages,
  sizeof(struct t37_debug), GFP_KERNEL);
-- 
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 v7 08/11] Input: atmel_mxt_ts - add diagnostic data support for mXT1386

2016-07-08 Thread Nick Dyer
The mXT1386 family of chips have a different architecture which splits
the diagnostic data into 3 columns.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/atmel_mxt_ts.c |   31 +++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index c35fca0..7c4d937 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -137,6 +137,10 @@ struct t9_range {
 #define MXT_DIAGNOSTIC_DELTAS  0x10
 #define MXT_DIAGNOSTIC_SIZE128
 
+#define MXT_FAMILY_1386160
+#define MXT1386_COLUMNS3
+#define MXT1386_PAGES_PER_COLUMN   8
+
 struct t37_debug {
 #ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
u8 mode;
@@ -2140,13 +2144,27 @@ recheck:
 static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
   unsigned int y)
 {
+   struct mxt_info *info = >info;
struct mxt_dbg *dbg = >dbg;
unsigned int ofs, page;
+   unsigned int col = 0;
+   unsigned int col_width;
+
+   if (info->family_id == MXT_FAMILY_1386) {
+   col_width = info->matrix_ysize / MXT1386_COLUMNS;
+   col = y / col_width;
+   y = y % col_width;
+   } else {
+   col_width = info->matrix_ysize;
+   }
 
-   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   ofs = (y + (x * col_width)) * sizeof(u16);
page = ofs / MXT_DIAGNOSTIC_SIZE;
ofs %= MXT_DIAGNOSTIC_SIZE;
 
+   if (info->family_id == MXT_FAMILY_1386)
+   page += col * MXT1386_PAGES_PER_COLUMN;
+
return get_unaligned_le16(>t37_buf[page].data[ofs]);
 }
 
@@ -2416,6 +2434,7 @@ static const struct video_device mxt_video_device = {
 
 static void mxt_debug_init(struct mxt_data *data)
 {
+   struct mxt_info *info = >info;
struct mxt_dbg *dbg = >dbg;
struct mxt_object *object;
int error;
@@ -2439,8 +2458,14 @@ static void mxt_debug_init(struct mxt_data *data)
 
/* Calculate size of data and allocate buffer */
dbg->t37_nodes = data->xsize * data->ysize;
-   dbg->t37_pages = DIV_ROUND_UP(data->xsize * data->info.matrix_ysize *
- sizeof(u16), sizeof(dbg->t37_buf->data));
+
+   if (info->family_id == MXT_FAMILY_1386)
+   dbg->t37_pages = MXT1386_COLUMNS * MXT1386_PAGES_PER_COLUMN;
+   else
+   dbg->t37_pages = DIV_ROUND_UP(data->xsize *
+ data->info.matrix_ysize *
+ sizeof(u16),
+ sizeof(dbg->t37_buf->data));
 
dbg->t37_buf = devm_kmalloc_array(>client->dev, dbg->t37_pages,
  sizeof(struct t37_debug), GFP_KERNEL);
-- 
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 v7 10/11] Input: synaptics-rmi4 - add support for F54 diagnostics

2016-07-08 Thread Nick Dyer
Function 54 implements access to various RMI4 diagnostic features.

This patch adds support for retrieving this data. It registers a V4L2
device to output the data to user space.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
Tested-by: Andrew Duggan <adug...@synaptics.com>
Tested-by: Chris Healy <cphe...@gmail.com>
---
 drivers/input/rmi4/Kconfig  |   11 +
 drivers/input/rmi4/Makefile |1 +
 drivers/input/rmi4/rmi_bus.c|3 +
 drivers/input/rmi4/rmi_driver.h |1 +
 drivers/input/rmi4/rmi_f54.c|  755 +++
 5 files changed, 771 insertions(+)
 create mode 100644 drivers/input/rmi4/rmi_f54.c

diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
index f73df24..f3418b6 100644
--- a/drivers/input/rmi4/Kconfig
+++ b/drivers/input/rmi4/Kconfig
@@ -61,3 +61,14 @@ config RMI4_F30
 
  Function 30 provides GPIO and LED support for RMI4 devices. This
  includes support for buttons on TouchPads and ClickPads.
+
+config RMI4_F54
+   bool "RMI4 Function 54 (Analog diagnostics)"
+   depends on RMI4_CORE
+   depends on VIDEO_V4L2
+   select VIDEOBUF2_VMALLOC
+   help
+ Say Y here if you want to add support for RMI4 function 54
+
+ Function 54 provides access to various diagnostic features in certain
+ RMI4 touch sensors.
diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index 95c00a7..0bafc85 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -7,6 +7,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
+rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 
 # Transports
 obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o
diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index b368b05..3aedc65 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -315,6 +315,9 @@ static struct rmi_function_handler *fn_handlers[] = {
 #ifdef CONFIG_RMI4_F30
_f30_handler,
 #endif
+#ifdef CONFIG_RMI4_F54
+   _f54_handler,
+#endif
 };
 
 static void __rmi_unregister_function_handlers(int start_idx)
diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
index 6e140fa..8dfbebe 100644
--- a/drivers/input/rmi4/rmi_driver.h
+++ b/drivers/input/rmi4/rmi_driver.h
@@ -102,4 +102,5 @@ extern struct rmi_function_handler rmi_f01_handler;
 extern struct rmi_function_handler rmi_f11_handler;
 extern struct rmi_function_handler rmi_f12_handler;
 extern struct rmi_function_handler rmi_f30_handler;
+extern struct rmi_function_handler rmi_f54_handler;
 #endif
diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c
new file mode 100644
index 000..bf0ada8
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f54.c
@@ -0,0 +1,755 @@
+/*
+ * Copyright (c) 2012-2015 Synaptics Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "rmi_driver.h"
+
+#define F54_NAME   "rmi4_f54"
+
+/* F54 data offsets */
+#define F54_REPORT_DATA_OFFSET  3
+#define F54_FIFO_OFFSET 1
+#define F54_NUM_TX_OFFSET   1
+#define F54_NUM_RX_OFFSET   0
+
+/* F54 commands */
+#define F54_GET_REPORT  1
+#define F54_FORCE_CAL   2
+
+/* Fixed sizes of reports */
+#define F54_QUERY_LEN  27
+
+/* F54 capabilities */
+#define F54_CAP_BASELINE   (1 << 2)
+#define F54_CAP_IMAGE8 (1 << 3)
+#define F54_CAP_IMAGE16(1 << 6)
+
+/**
+ * enum rmi_f54_report_type - RMI4 F54 report types
+ *
+ * @F54_8BIT_IMAGE:Normalized 8-Bit Image Report. The capacitance variance
+ * from baseline for each pixel.
+ *
+ * @F54_16BIT_IMAGE:   Normalized 16-Bit Image Report. The capacitance variance
+ * from baseline for each pixel.
+ *
+ * @F54_RAW_16BIT_IMAGE:
+ * Raw 16-Bit Image Report. The raw capacitance for each
+ * pixel.
+ *
+ * @F54_TRUE_BASELINE: True Baseline Report. The baseline capacitance for each
+ * pixel.
+ *
+ * @F54_FULL_RAW_CAP:   Full Raw Capacitance Report. The raw capacitance with
+ * low reference set to its minimum value and high
+ * reference set to its maximum value.
+ *
+ * @F54_FULL_RAW_CAP_RX_OFFSET_REMOVED:
+ * Full Raw Capacitance with Receiver Offset Removed
+ * Report. Set Low reference to its minimum value and high
+ * references to its maximum value, then report the raw
+ * 

[PATCH v7 06/11] Input: atmel_mxt_ts - read touchscreen size

2016-07-08 Thread Nick Dyer
The touchscreen may have a margin where not all the matrix is used. Read
the parameters from T9 and T100 and take account of the difference.

Note: this does not read the XORIGIN/YORIGIN fields so it assumes that
the touchscreen starts at (0,0)

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/atmel_mxt_ts.c |   42 +-
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index bea95a1..d09ecc3 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -103,6 +103,8 @@ struct t7_config {
 
 /* MXT_TOUCH_MULTI_T9 field */
 #define MXT_T9_CTRL0
+#define MXT_T9_XSIZE   3
+#define MXT_T9_YSIZE   4
 #define MXT_T9_ORIENT  9
 #define MXT_T9_RANGE   18
 
@@ -150,7 +152,9 @@ struct t37_debug {
 #define MXT_T100_CTRL  0
 #define MXT_T100_CFG1  1
 #define MXT_T100_TCHAUX3
+#define MXT_T100_XSIZE 9
 #define MXT_T100_XRANGE13
+#define MXT_T100_YSIZE 20
 #define MXT_T100_YRANGE24
 
 #define MXT_T100_CFG_SWITCHXY  BIT(5)
@@ -259,6 +263,8 @@ struct mxt_data {
unsigned int max_x;
unsigned int max_y;
bool xy_switch;
+   u8 xsize;
+   u8 ysize;
bool in_bootloader;
u16 mem_size;
u8 t100_aux_ampl;
@@ -1714,6 +1720,18 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return -EINVAL;
 
error = __mxt_read_reg(client,
+  object->start_address + MXT_T9_XSIZE,
+  sizeof(data->xsize), >xsize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T9_YSIZE,
+  sizeof(data->ysize), >ysize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
   object->start_address + MXT_T9_RANGE,
   sizeof(range), );
if (error)
@@ -1763,6 +1781,18 @@ static int mxt_read_t100_config(struct mxt_data *data)
 
data->max_y = get_unaligned_le16(_y);
 
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T100_XSIZE,
+  sizeof(data->xsize), >xsize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T100_YSIZE,
+  sizeof(data->ysize), >ysize);
+   if (error)
+   return error;
+
/* read orientation config */
error =  __mxt_read_reg(client,
object->start_address + MXT_T100_CFG1,
@@ -2121,7 +2151,7 @@ static int mxt_convert_debug_pages(struct mxt_data *data, 
u16 *outbuf)
outbuf[i] = mxt_get_debug_value(data, x, y);
 
/* Next value */
-   if (++x >= data->info.matrix_xsize) {
+   if (++x >= data->xsize) {
x = 0;
y++;
}
@@ -2276,8 +2306,8 @@ static int mxt_set_input(struct mxt_data *data, unsigned 
int i)
if (i > 0)
return -EINVAL;
 
-   f->width = data->info.matrix_xsize;
-   f->height = data->info.matrix_ysize;
+   f->width = data->xsize;
+   f->height = data->ysize;
f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
@@ -2392,9 +2422,9 @@ static void mxt_debug_init(struct mxt_data *data)
dbg->t37_address = object->start_address;
 
/* Calculate size of data and allocate buffer */
-   dbg->t37_nodes = data->info.matrix_xsize * data->info.matrix_ysize;
-   dbg->t37_pages = DIV_ROUND_UP(dbg->t37_nodes * sizeof(u16),
- sizeof(dbg->t37_buf->data));
+   dbg->t37_nodes = data->xsize * data->ysize;
+   dbg->t37_pages = DIV_ROUND_UP(data->xsize * data->info.matrix_ysize *
+ sizeof(u16), sizeof(dbg->t37_buf->data));
 
dbg->t37_buf = devm_kmalloc_array(>client->dev, dbg->t37_pages,
  sizeof(struct t37_debug), GFP_KERNEL);
-- 
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 v7 03/11] DocBook: add support for touch devices

2016-07-08 Thread Nick Dyer
Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 Documentation/DocBook/media/v4l/dev-touch.xml  |   51 
 Documentation/DocBook/media/v4l/media-types.xml|5 ++
 .../DocBook/media/v4l/pixfmt-tch-td08.xml  |   66 
 .../DocBook/media/v4l/pixfmt-tch-td16.xml  |   82 
 .../DocBook/media/v4l/pixfmt-tch-tu08.xml  |   66 
 .../DocBook/media/v4l/pixfmt-tch-tu16.xml  |   81 +++
 Documentation/DocBook/media/v4l/pixfmt.xml |   13 
 Documentation/DocBook/media/v4l/v4l2.xml   |1 +
 8 files changed, 365 insertions(+)
 create mode 100644 Documentation/DocBook/media/v4l/dev-touch.xml
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-tch-td08.xml
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-tch-td16.xml
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-tch-tu08.xml
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-tch-tu16.xml

diff --git a/Documentation/DocBook/media/v4l/dev-touch.xml 
b/Documentation/DocBook/media/v4l/dev-touch.xml
new file mode 100644
index 000..85d492a
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/dev-touch.xml
@@ -0,0 +1,51 @@
+Touch Devices
+
+Touch devices are accessed through character device special files
+  named /dev/v4l-touch0 to
+  /dev/v4l-touch255 with major number 81 and
+  dynamically allocated minor numbers 0 to 255.
+
+
+  Overview
+
+  Sensors may be Optical, or Projected Capacitive touch (PCT).
+
+  Processing is required to analyse the raw data and produce input
+events. In some systems, this may be performed on the ASIC and the raw data
+is purely a side-channel for diagnostics or tuning. In other systems, the
+ASIC is a simple analogue front end device which delivers touch data at
+high rate, and any touch processing must be done on the host.
+
+  For capacitive touch sensing, the touchscreen is composed of an array
+of horizontal and vertical conductors (alternatively called rows/columns,
+X/Y lines, or tx/rx). Mutual Capacitance measured is at the nodes where the
+conductors cross. Alternatively, Self Capacitance measures the signal from
+each column and row independently.
+
+  A touch input may be determined by comparing the raw capacitance
+measurement to a no-touch reference (or "baseline") measurement:
+
+  Delta = Raw - Reference
+
+  The reference measurement takes account of variations in the
+capacitance across the touch sensor matrix, for example
+manufacturing irregularities, environmental or edge effects.
+
+
+
+  Querying Capabilities
+
+  Devices supporting the touch interface set the
+V4L2_CAP_VIDEO_CAPTURE flag in the
+capabilities field of 
+returned by the  ioctl.
+
+  At least one of the read/write or streaming I/O methods must be
+supported.
+
+
+
+  Data Format Negotiation
+
+  A touch device may support any I/O method.
+
diff --git a/Documentation/DocBook/media/v4l/media-types.xml 
b/Documentation/DocBook/media/v4l/media-types.xml
index 5e3f20f..fb957c7 100644
--- a/Documentation/DocBook/media/v4l/media-types.xml
+++ b/Documentation/DocBook/media/v4l/media-types.xml
@@ -202,6 +202,11 @@
typically, /dev/swradio?
  
  
+   MEDIA_INTF_T_V4L_TOUCH
+   Device node interface for Touch device (V4L)
+   typically, /dev/v4l-touch?
+ 
+ 
MEDIA_INTF_T_ALSA_PCM_CAPTURE
Device node interface for ALSA PCM Capture
typically, /dev/snd/pcmC?D?c
diff --git a/Documentation/DocBook/media/v4l/pixfmt-tch-td08.xml 
b/Documentation/DocBook/media/v4l/pixfmt-tch-td08.xml
new file mode 100644
index 000..2483eb0
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/pixfmt-tch-td08.xml
@@ -0,0 +1,66 @@
+
+  
+V4L2_TCH_FMT_DELTA_TD08 ('TD08')
+
+  
+  
+V4L2_TCH_FMT_DELTA_TD08
+8-bit signed Touch Delta
+  
+  
+Description
+
+This format represents delta data from a touch controller
+
+Delta values may range from -128 to 127. Typically the values
+  will vary through a small range depending on whether the sensor is
+  touched or not. The full value may be seen if one of the
+  touchscreen nodes has a fault or the line is not connected.
+
+
+  V4L2_TCH_FMT_DELTA_TD08 4  4
+node matrix
+
+  
+Byte Order.
+Each cell is one byte.
+  
+
+  
+  
+
+  start+0:
+  D'00
+  D'01
+  D'02
+  D'03
+
+
+  start+4:
+  D'10
+  D'11
+  D'12
+  D'13
+
+
+  start+8:
+  D'20
+  D'21
+  D'22
+  

[PATCH v7 07/11] Input: atmel_mxt_ts - handle diagnostic data orientation

2016-07-08 Thread Nick Dyer
Invert the diagnostic data to match the orientation of the input device.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/atmel_mxt_ts.c |   26 +-
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index d09ecc3..c35fca0 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -125,6 +125,8 @@ struct t9_range {
 
 /* MXT_TOUCH_MULTI_T9 orient */
 #define MXT_T9_ORIENT_SWITCH   (1 << 0)
+#define MXT_T9_ORIENT_INVERTX  (1 << 1)
+#define MXT_T9_ORIENT_INVERTY  (1 << 2)
 
 /* MXT_SPT_COMMSCONFIG_T18 */
 #define MXT_COMMS_CTRL 0
@@ -158,6 +160,8 @@ struct t37_debug {
 #define MXT_T100_YRANGE24
 
 #define MXT_T100_CFG_SWITCHXY  BIT(5)
+#define MXT_T100_CFG_INVERTY   BIT(6)
+#define MXT_T100_CFG_INVERTX   BIT(7)
 
 #define MXT_T100_TCHAUX_VECT   BIT(0)
 #define MXT_T100_TCHAUX_AMPL   BIT(1)
@@ -262,6 +266,8 @@ struct mxt_data {
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
+   bool invertx;
+   bool inverty;
bool xy_switch;
u8 xsize;
u8 ysize;
@@ -1747,6 +1753,8 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return error;
 
data->xy_switch = orient & MXT_T9_ORIENT_SWITCH;
+   data->invertx = orient & MXT_T9_ORIENT_INVERTX;
+   data->inverty = orient & MXT_T9_ORIENT_INVERTY;
 
return 0;
 }
@@ -1801,6 +1809,8 @@ static int mxt_read_t100_config(struct mxt_data *data)
return error;
 
data->xy_switch = cfg & MXT_T100_CFG_SWITCHXY;
+   data->invertx = cfg & MXT_T100_CFG_INVERTX;
+   data->inverty = cfg & MXT_T100_CFG_INVERTY;
 
/* allocate aux bytes */
error =  __mxt_read_reg(client,
@@ -2145,13 +2155,19 @@ static int mxt_convert_debug_pages(struct mxt_data 
*data, u16 *outbuf)
struct mxt_dbg *dbg = >dbg;
unsigned int x = 0;
unsigned int y = 0;
-   unsigned int i;
+   unsigned int i, rx, ry;
 
for (i = 0; i < dbg->t37_nodes; i++) {
-   outbuf[i] = mxt_get_debug_value(data, x, y);
+   /* Handle orientation */
+   rx = data->xy_switch ? y : x;
+   ry = data->xy_switch ? x : y;
+   rx = data->invertx ? (data->xsize - 1 - rx) : rx;
+   ry = data->inverty ? (data->ysize - 1 - ry) : ry;
+
+   outbuf[i] = mxt_get_debug_value(data, rx, ry);
 
/* Next value */
-   if (++x >= data->xsize) {
+   if (++x >= (data->xy_switch ? data->ysize : data->xsize)) {
x = 0;
y++;
}
@@ -2306,8 +2322,8 @@ static int mxt_set_input(struct mxt_data *data, unsigned 
int i)
if (i > 0)
return -EINVAL;
 
-   f->width = data->xsize;
-   f->height = data->ysize;
+   f->width = data->xy_switch ? data->ysize : data->xsize;
+   f->height = data->xy_switch ? data->xsize : data->ysize;
f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
-- 
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 v7 05/11] Input: atmel_mxt_ts - output diagnostic debug via V4L2 device

2016-07-08 Thread Nick Dyer
Register a video device to output T37 diagnostic data.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/Kconfig|6 +-
 drivers/input/touchscreen/atmel_mxt_ts.c |  244 ++
 2 files changed, 248 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index da96ecf..7c1c5ec 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -117,9 +117,11 @@ config TOUCHSCREEN_ATMEL_MXT
 
 config TOUCHSCREEN_ATMEL_MXT_T37
bool "Support T37 Diagnostic Data"
-   depends on TOUCHSCREEN_ATMEL_MXT
+   depends on TOUCHSCREEN_ATMEL_MXT && VIDEO_V4L2
+   select VIDEOBUF2_VMALLOC
help
- Say Y here if you want support for the T37 Diagnostic Data object.
+ Say Y here if you want support to output data from the T37
+ Diagnostic Data object using a V4L device.
 
 config TOUCHSCREEN_AUO_PIXCIR
tristate "AUO in-cell touchscreen using Pixcir ICs"
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 0048233..bea95a1 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -28,6 +28,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 /* Firmware files */
 #define MXT_FW_NAME"maxtouch.fw"
@@ -224,6 +228,23 @@ struct mxt_dbg {
struct t37_debug *t37_buf;
unsigned int t37_pages;
unsigned int t37_nodes;
+
+   struct v4l2_device v4l2;
+   struct v4l2_pix_format format;
+   struct video_device vdev;
+   struct vb2_queue queue;
+   struct mutex lock;
+   int input;
+};
+
+static const struct v4l2_file_operations mxt_video_fops = {
+   .owner = THIS_MODULE,
+   .open = v4l2_fh_open,
+   .release = vb2_fop_release,
+   .unlocked_ioctl = video_ioctl2,
+   .read = vb2_fop_read,
+   .mmap = vb2_fop_mmap,
+   .poll = vb2_fop_poll,
 };
 
 /* Each client has this additional data */
@@ -279,6 +300,11 @@ struct mxt_data {
struct completion crc_completion;
 };
 
+struct mxt_vb2_buffer {
+   struct vb2_buffer   vb;
+   struct list_headlist;
+};
+
 static size_t mxt_obj_size(const struct mxt_object *obj)
 {
return obj->size_minus_one + 1;
@@ -1525,6 +1551,11 @@ static void mxt_free_input_device(struct mxt_data *data)
 
 static void mxt_free_object_table(struct mxt_data *data)
 {
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+   video_unregister_device(>dbg.vdev);
+   v4l2_device_unregister(>dbg.v4l2);
+#endif
+
kfree(data->object_table);
data->object_table = NULL;
kfree(data->msg_buf);
@@ -2157,10 +2188,191 @@ wait_cmd:
return mxt_convert_debug_pages(data, outbuf);
 }
 
+static int mxt_queue_setup(struct vb2_queue *q,
+  unsigned int *nbuffers, unsigned int *nplanes,
+  unsigned int sizes[], void *alloc_ctxs[])
+{
+   struct mxt_data *data = q->drv_priv;
+   size_t size = data->dbg.t37_nodes * sizeof(u16);
+
+   if (*nplanes)
+   return sizes[0] < size ? -EINVAL : 0;
+
+   *nplanes = 1;
+   sizes[0] = size;
+
+   return 0;
+}
+
+static void mxt_buffer_queue(struct vb2_buffer *vb)
+{
+   struct mxt_data *data = vb2_get_drv_priv(vb->vb2_queue);
+   u16 *ptr;
+   int ret;
+
+   ptr = vb2_plane_vaddr(vb, 0);
+   if (!ptr) {
+   dev_err(>client->dev, "Error acquiring frame ptr\n");
+   goto fault;
+   }
+
+   ret = mxt_read_diagnostic_debug(data, MXT_DIAGNOSTIC_DELTAS, ptr);
+   if (ret)
+   goto fault;
+
+   vb2_set_plane_payload(vb, 0, data->dbg.t37_nodes * sizeof(u16));
+   vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+   return;
+
+fault:
+   vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+}
+
+/* V4L2 structures */
+static const struct vb2_ops mxt_queue_ops = {
+   .queue_setup= mxt_queue_setup,
+   .buf_queue  = mxt_buffer_queue,
+   .wait_prepare   = vb2_ops_wait_prepare,
+   .wait_finish= vb2_ops_wait_finish,
+};
+
+static const struct vb2_queue mxt_queue = {
+   .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+   .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ,
+   .buf_struct_size = sizeof(struct mxt_vb2_buffer),
+   .ops = _queue_ops,
+   .mem_ops = _vmalloc_memops,
+   .timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC,
+   .min_buffers_needed = 1,
+};
+
+static int mxt_vidioc_querycap(struct file *file, void *priv,
+struct v4l2_capability *cap)
+{
+   struct mxt_data *data = video_drvdata(file);
+
+   strlcpy(cap->driver, "atmel_mxt_ts", sizeof(cap->driver));
+ 

[PATCH v7 0/11] Output raw touch data via V4L2

2016-07-08 Thread Nick Dyer
This is a series of patches to add output of raw touch diagnostic data via V4L2
to the Atmel maXTouch and Synaptics RMI4 drivers.

It's a rewrite of the previous implementation which output via debugfs: it now
uses a V4L2 device in a similar way to the sur40 driver.

We have a utility which can read the data and display it in a useful format:
https://github.com/ndyer/heatmap/commits/heatmap-v4l

These patches are also available from
https://github.com/ndyer/linux/commits/v4l-touch-v7-2016-07-08

I will also send a patch to update v4l2-compliance.

Changes in v7:
- Tested by Andrew Duggan and Chris Healy.
- Update bus_info to add "rmi4:" bus.
- Fix code style issues in sur40 changes.

Changes in v6:
- Remove BUF_TYPE_TOUCH_CAPTURE, as discussed with Hans V touch devices will
  use BUF_TYPE_VIDEO_CAPTURE.
- Touch devices should now register CAP_VIDEO_CAPTURE: CAP_TOUCH just says that
  this is a touch device, not a video device, but otherwise it acts the same.
- Add some code to v4l_s_fmt() to set sensible default values for fields not
  used by touch.
- Improve naming/doc of RMI4 F54 report types.
- Various minor DocBook fixes, and split to separate patch.
- Update my email address.
- Rework sur40 changes so that PIX_FMT_GREY is supported for backward
  compatibility. Florian is it possible for you to test?

Changes in v5 (Hans Verkuil review):
- Update v4l2-core:
  - Add VFL_TYPE_TOUCH, V4L2_BUF_TYPE_TOUCH_CAPTURE and V4L2_CAP_TOUCH
  - Change V4L2_INPUT_TYPE_TOUCH_SENSOR to V4L2_INPUT_TYPE_TOUCH
  - Improve DocBook documentation
  - Add FMT definitions for touch data
  - Note this will need the latest version of the heatmap util
- Synaptics RMI4 driver:
  - Remove some less important non full frame report types
  - Switch report type names to const char * array
  - Move a static array to inside context struct
- Split sur40 changes to a separate commit

Changes in v4:
- Address nits from the input side in atmel_mxt_ts patches (Dmitry Torokhov)
- Add Synaptics RMI4 F54 support patch

Changes in v3:
- Address V4L2 review comments from Hans Verkuil
- Run v4l-compliance and fix all issues - needs minor patch here:
  https://github.com/ndyer/v4l-utils/commit/cf50469773f

Changes in v2:
- Split pixfmt changes into separate commit and add DocBook
- Introduce VFL_TYPE_TOUCH_SENSOR and /dev/v4l-touch
- Remove "single node" support for now, it may be better to treat it as
  metadata later
- Explicitly set VFL_DIR_RX
- Fix Kconfig

--
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 v7 04/11] Input: atmel_mxt_ts - add support for T37 diagnostic data

2016-07-08 Thread Nick Dyer
Atmel maXTouch devices have a T37 object which can be used to read raw
touch deltas from the device. This consists of an array of 16-bit
integers, one for each node on the touchscreen matrix.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/Kconfig|6 ++
 drivers/input/touchscreen/atmel_mxt_ts.c |  159 ++
 2 files changed, 165 insertions(+)

diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index 8ecdc38..da96ecf 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -115,6 +115,12 @@ config TOUCHSCREEN_ATMEL_MXT
  To compile this driver as a module, choose M here: the
  module will be called atmel_mxt_ts.
 
+config TOUCHSCREEN_ATMEL_MXT_T37
+   bool "Support T37 Diagnostic Data"
+   depends on TOUCHSCREEN_ATMEL_MXT
+   help
+ Say Y here if you want support for the T37 Diagnostic Data object.
+
 config TOUCHSCREEN_AUO_PIXCIR
tristate "AUO in-cell touchscreen using Pixcir ICs"
depends on I2C
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 5af7907..0048233 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -124,6 +124,19 @@ struct t9_range {
 #define MXT_COMMS_CTRL 0
 #define MXT_COMMS_CMD  1
 
+/* MXT_DEBUG_DIAGNOSTIC_T37 */
+#define MXT_DIAGNOSTIC_PAGEUP  0x01
+#define MXT_DIAGNOSTIC_DELTAS  0x10
+#define MXT_DIAGNOSTIC_SIZE128
+
+struct t37_debug {
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+   u8 mode;
+   u8 page;
+   u8 data[MXT_DIAGNOSTIC_SIZE];
+#endif
+};
+
 /* Define for MXT_GEN_COMMAND_T6 */
 #define MXT_BOOT_VALUE 0xa5
 #define MXT_RESET_VALUE0x01
@@ -205,6 +218,14 @@ struct mxt_object {
u8 num_report_ids;
 } __packed;
 
+struct mxt_dbg {
+   u16 t37_address;
+   u16 diag_cmd_address;
+   struct t37_debug *t37_buf;
+   unsigned int t37_pages;
+   unsigned int t37_nodes;
+};
+
 /* Each client has this additional data */
 struct mxt_data {
struct i2c_client *client;
@@ -233,6 +254,7 @@ struct mxt_data {
u8 num_touchids;
u8 multitouch;
struct t7_config t7_cfg;
+   struct mxt_dbg dbg;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -2043,6 +2065,141 @@ recheck:
return 0;
 }
 
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
+  unsigned int y)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int ofs, page;
+
+   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   page = ofs / MXT_DIAGNOSTIC_SIZE;
+   ofs %= MXT_DIAGNOSTIC_SIZE;
+
+   return get_unaligned_le16(>t37_buf[page].data[ofs]);
+}
+
+static int mxt_convert_debug_pages(struct mxt_data *data, u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int x = 0;
+   unsigned int y = 0;
+   unsigned int i;
+
+   for (i = 0; i < dbg->t37_nodes; i++) {
+   outbuf[i] = mxt_get_debug_value(data, x, y);
+
+   /* Next value */
+   if (++x >= data->info.matrix_xsize) {
+   x = 0;
+   y++;
+   }
+   }
+
+   return 0;
+}
+
+static int mxt_read_diagnostic_debug(struct mxt_data *data, u8 mode,
+u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   int retries = 0;
+   int page;
+   int ret;
+   u8 cmd = mode;
+   struct t37_debug *p;
+   u8 cmd_poll;
+
+   for (page = 0; page < dbg->t37_pages; page++) {
+   p = dbg->t37_buf + page;
+
+   ret = mxt_write_reg(data->client, dbg->diag_cmd_address,
+   cmd);
+   if (ret)
+   return ret;
+
+   retries = 0;
+   msleep(20);
+wait_cmd:
+   /* Read back command byte */
+   ret = __mxt_read_reg(data->client, dbg->diag_cmd_address,
+sizeof(cmd_poll), _poll);
+   if (ret)
+   return ret;
+
+   /* Field is cleared once the command has been processed */
+   if (cmd_poll) {
+   if (retries++ > 100)
+   return -EINVAL;
+
+   msleep(20);
+   goto wait_cmd;
+   }
+
+   /* Read T37 page */
+   ret = __mxt_read_reg(data->client, dbg->t37_address,
+sizeof(struct t37_debug), p);
+   if (ret)
+   return ret;
+
+   if (p->mode != mode || p->page != page) {
+  

[PATCH v7 11/11] Input: sur40 - use new V4L2 touch input type

2016-07-08 Thread Nick Dyer
Support both V4L2_TCH_FMT_TU08 and V4L2_PIX_FMT_GREY for backwards
compatibility.

Note: I have not tested these changes (I have no access to the hardware)
so not signing off.
---
 drivers/input/touchscreen/sur40.c |  123 +++--
 1 file changed, 89 insertions(+), 34 deletions(-)

diff --git a/drivers/input/touchscreen/sur40.c 
b/drivers/input/touchscreen/sur40.c
index 880c40b..b6cbe74 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -139,6 +139,27 @@ struct sur40_image_header {
 #define SUR40_GET_STATE   0xc5 /*  4 bytes state (?) */
 #define SUR40_GET_SENSORS 0xb1 /*  8 bytes sensors   */
 
+static const struct v4l2_pix_format sur40_pix_format[] = {
+   {
+   .pixelformat = V4L2_TCH_FMT_TU08,
+   .width  = SENSOR_RES_X / 2,
+   .height = SENSOR_RES_Y / 2,
+   .field = V4L2_FIELD_NONE,
+   .colorspace = V4L2_COLORSPACE_SRGB,
+   .bytesperline = SENSOR_RES_X / 2,
+   .sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
+   },
+   {
+   .pixelformat = V4L2_PIX_FMT_GREY,
+   .width  = SENSOR_RES_X / 2,
+   .height = SENSOR_RES_Y / 2,
+   .field = V4L2_FIELD_NONE,
+   .colorspace = V4L2_COLORSPACE_SRGB,
+   .bytesperline = SENSOR_RES_X / 2,
+   .sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
+   }
+};
+
 /* master device state */
 struct sur40_state {
 
@@ -149,6 +170,7 @@ struct sur40_state {
struct v4l2_device v4l2;
struct video_device vdev;
struct mutex lock;
+   struct v4l2_pix_format pix_fmt;
 
struct vb2_queue queue;
struct vb2_alloc_ctx *alloc_ctx;
@@ -170,7 +192,6 @@ struct sur40_buffer {
 
 /* forward declarations */
 static const struct video_device sur40_video_device;
-static const struct v4l2_pix_format sur40_video_format;
 static const struct vb2_queue sur40_queue;
 static void sur40_process_video(struct sur40_state *sur40);
 
@@ -421,7 +442,7 @@ static void sur40_process_video(struct sur40_state *sur40)
goto err_poll;
}
 
-   if (le32_to_cpu(img->size) != sur40_video_format.sizeimage) {
+   if (le32_to_cpu(img->size) != sur40->pix_fmt.sizeimage) {
dev_err(sur40->dev, "image size mismatch\n");
goto err_poll;
}
@@ -432,7 +453,7 @@ static void sur40_process_video(struct sur40_state *sur40)
 
result = usb_sg_init(, sur40->usbdev,
usb_rcvbulkpipe(sur40->usbdev, VIDEO_ENDPOINT), 0,
-   sgt->sgl, sgt->nents, sur40_video_format.sizeimage, 0);
+   sgt->sgl, sgt->nents, sur40->pix_fmt.sizeimage, 0);
if (result < 0) {
dev_err(sur40->dev, "error %d in usb_sg_init\n", result);
goto err_poll;
@@ -593,13 +614,14 @@ static int sur40_probe(struct usb_interface *interface,
goto err_unreg_v4l2;
}
 
+   sur40->pix_fmt = sur40_pix_format[0];
sur40->vdev = sur40_video_device;
sur40->vdev.v4l2_dev = >v4l2;
sur40->vdev.lock = >lock;
sur40->vdev.queue = >queue;
video_set_drvdata(>vdev, sur40);
 
-   error = video_register_device(>vdev, VFL_TYPE_GRABBER, -1);
+   error = video_register_device(>vdev, VFL_TYPE_TOUCH, -1);
if (error) {
dev_err(>dev,
"Unable to register video subdevice.");
@@ -662,10 +684,10 @@ static int sur40_queue_setup(struct vb2_queue *q,
alloc_ctxs[0] = sur40->alloc_ctx;
 
if (*nplanes)
-   return sizes[0] < sur40_video_format.sizeimage ? -EINVAL : 0;
+   return sizes[0] < sur40->pix_fmt.sizeimage ? -EINVAL : 0;
 
*nplanes = 1;
-   sizes[0] = sur40_video_format.sizeimage;
+   sizes[0] = sur40->pix_fmt.sizeimage;
 
return 0;
 }
@@ -677,7 +699,7 @@ static int sur40_queue_setup(struct vb2_queue *q,
 static int sur40_buffer_prepare(struct vb2_buffer *vb)
 {
struct sur40_state *sur40 = vb2_get_drv_priv(vb->vb2_queue);
-   unsigned long size = sur40_video_format.sizeimage;
+   unsigned long size = sur40->pix_fmt.sizeimage;
 
if (vb2_plane_size(vb, 0) < size) {
dev_err(>usbdev->dev, "buffer too small (%lu < %lu)\n",
@@ -751,7 +773,7 @@ static int sur40_vidioc_querycap(struct file *file, void 
*priv,
strlcpy(cap->driver, DRIVER_SHORT, sizeof(cap->driver));
strlcpy(cap->card, DRIVER_LONG, sizeof(cap->card));
usb_make_path(sur40->usbdev, cap->bus_info, sizeof(cap->bus_info));
-   cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
+   cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TOUCH |
V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING;
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -763,7 +785,7 @@ static int sur40_vidioc_enum_input(struct file *file, void 

[PATCH] v4l2-compliance: Changes to support touch sensors

2016-07-08 Thread Nick Dyer
Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 utils/v4l2-compliance/v4l2-compliance.cpp|   51 +-
 utils/v4l2-compliance/v4l2-compliance.h  |1 +
 utils/v4l2-compliance/v4l2-test-input-output.cpp |4 +-
 3 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp 
b/utils/v4l2-compliance/v4l2-compliance.cpp
index 48dc8b4..ca2eec7 100644
--- a/utils/v4l2-compliance/v4l2-compliance.cpp
+++ b/utils/v4l2-compliance/v4l2-compliance.cpp
@@ -55,6 +55,7 @@ enum Option {
OptSetRadioDevice = 'r',
OptStreaming = 's',
OptSetSWRadioDevice = 'S',
+   OptSetTouchDevice = 't',
OptTrace = 'T',
OptVerbose = 'v',
OptSetVbiDevice = 'V',
@@ -105,6 +106,7 @@ static struct option long_options[] = {
{"vbi-device", required_argument, 0, OptSetVbiDevice},
{"sdr-device", required_argument, 0, OptSetSWRadioDevice},
{"expbuf-device", required_argument, 0, OptSetExpBufDevice},
+   {"touch-device", required_argument, 0, OptSetTouchDevice},
{"help", no_argument, 0, OptHelp},
{"verbose", no_argument, 0, OptVerbose},
{"no-warnings", no_argument, 0, OptNoWarnings},
@@ -134,6 +136,9 @@ static void usage(void)
printf("  -S, --sdr-device=\n");
printf(" Use device  as the SDR device.\n");
printf(" If  starts with a digit, then 
/dev/swradio is used.\n");
+   printf("  -t, --touch-device=\n");
+   printf(" Use device  as the touch device.\n");
+   printf(" If  starts with a digit, then 
/dev/v4l-touch is used.\n");
printf("  -e, --expbuf-device=\n");
printf(" Use device  to obtain DMABUF 
handles.\n");
printf(" If  starts with a digit, then 
/dev/video is used.\n");
@@ -206,6 +211,8 @@ std::string cap2s(unsigned cap)
s += "\t\tSDR Capture\n";
if (cap & V4L2_CAP_SDR_OUTPUT)
s += "\t\tSDR Output\n";
+   if (cap & V4L2_CAP_TOUCH)
+   s += "\t\tTouch Capture\n";
if (cap & V4L2_CAP_TUNER)
s += "\t\tTuner\n";
if (cap & V4L2_CAP_HW_FREQ_SEEK)
@@ -533,7 +540,8 @@ static int testCap(struct node *node)
memcmp(vcap.bus_info, "ISA:", 4) &&
memcmp(vcap.bus_info, "I2C:", 4) &&
memcmp(vcap.bus_info, "parport", 7) &&
-   memcmp(vcap.bus_info, "platform:", 9))
+   memcmp(vcap.bus_info, "platform:", 9) &&
+   memcmp(vcap.bus_info, "rmi4:", 5))
return fail("missing bus_info prefix ('%s')\n", vcap.bus_info);
fail_on_test((vcap.version >> 16) < 3);
fail_on_test(check_0(vcap.reserved, sizeof(vcap.reserved)));
@@ -673,6 +681,8 @@ int main(int argc, char **argv)
struct node radio_node2;
struct node sdr_node;
struct node sdr_node2;
+   struct node touch_node;
+   struct node touch_node2;
struct node expbuf_node;
 
/* command args */
@@ -682,6 +692,7 @@ int main(int argc, char **argv)
const char *vbi_device = NULL;  /* -V device */
const char *radio_device = NULL;/* -r device */
const char *sdr_device = NULL;  /* -S device */
+   const char *touch_device = NULL;/* -t device */
const char *expbuf_device = NULL;   /* --expbuf-device device */
struct v4l2_capability vcap;/* list_cap */
unsigned frame_count = 60;
@@ -750,6 +761,15 @@ int main(int argc, char **argv)
sdr_device = newdev;
}
break;
+   case OptSetTouchDevice:
+   touch_device = optarg;
+   if (touch_device[0] >= '0' && touch_device[0] <= '9' && 
strlen(touch_device) <= 3) {
+   static char newdev[20];
+
+   sprintf(newdev, "/dev/v4l-touch%s", 
touch_device);
+   touch_device = newdev;
+   }
+   break;
case OptSetExpBufDevice:
expbuf_device = optarg;
if (expbuf_device[0] >= '0' && expbuf_device[0] <= '9' 
&& strlen(expbuf_device) <= 3) {
@@ -839,7 +859,8 @@ int main(int argc, char **argv)
if (v1 == 2 && v2 == 6)
kernel_version = v3;
 
-   if (!video_device && !vbi_device &

[PATCH v7 01/11] Input: atmel_mxt_ts - update MAINTAINERS email address

2016-07-08 Thread Nick Dyer
I'm leaving ITDev, so change to my personal email. My understanding is
that someone at Atmel will take this on once their takeover by Microchip
has settled down.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 MAINTAINERS |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1209323..0461f0d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2181,9 +2181,9 @@ S:Maintained
 F: drivers/net/wireless/atmel/atmel*
 
 ATMEL MAXTOUCH DRIVER
-M:     Nick Dyer <nick.d...@itdev.co.uk>
-T: git git://github.com/atmel-maxtouch/linux.git
-S: Supported
+M:     Nick Dyer <n...@shmanahar.org>
+T: git git://github.com/ndyer/linux.git
+S: Maintained
 F: Documentation/devicetree/bindings/input/atmel,maxtouch.txt
 F: drivers/input/touchscreen/atmel_mxt_ts.c
 F: include/linux/platform_data/atmel_mxt_ts.h
-- 
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 v7 09/11] Input: atmel_mxt_ts - add support for reference data

2016-07-08 Thread Nick Dyer
There are different datatypes available from a maXTouch chip. Add
support to retrieve reference data as well.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/atmel_mxt_ts.c |   57 ++
 1 file changed, 51 insertions(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 7c4d937..f75f2ce 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -135,6 +135,7 @@ struct t9_range {
 /* MXT_DEBUG_DIAGNOSTIC_T37 */
 #define MXT_DIAGNOSTIC_PAGEUP  0x01
 #define MXT_DIAGNOSTIC_DELTAS  0x10
+#define MXT_DIAGNOSTIC_REFS0x11
 #define MXT_DIAGNOSTIC_SIZE128
 
 #define MXT_FAMILY_1386160
@@ -249,6 +250,12 @@ struct mxt_dbg {
int input;
 };
 
+enum v4l_dbg_inputs {
+   MXT_V4L_INPUT_DELTAS,
+   MXT_V4L_INPUT_REFS,
+   MXT_V4L_INPUT_MAX,
+};
+
 static const struct v4l2_file_operations mxt_video_fops = {
.owner = THIS_MODULE,
.open = v4l2_fh_open,
@@ -2273,6 +2280,7 @@ static void mxt_buffer_queue(struct vb2_buffer *vb)
struct mxt_data *data = vb2_get_drv_priv(vb->vb2_queue);
u16 *ptr;
int ret;
+   u8 mode;
 
ptr = vb2_plane_vaddr(vb, 0);
if (!ptr) {
@@ -2280,7 +2288,18 @@ static void mxt_buffer_queue(struct vb2_buffer *vb)
goto fault;
}
 
-   ret = mxt_read_diagnostic_debug(data, MXT_DIAGNOSTIC_DELTAS, ptr);
+   switch (data->dbg.input) {
+   case MXT_V4L_INPUT_DELTAS:
+   default:
+   mode = MXT_DIAGNOSTIC_DELTAS;
+   break;
+
+   case MXT_V4L_INPUT_REFS:
+   mode = MXT_DIAGNOSTIC_REFS;
+   break;
+   }
+
+   ret = mxt_read_diagnostic_debug(data, mode, ptr);
if (ret)
goto fault;
 
@@ -2325,11 +2344,21 @@ static int mxt_vidioc_querycap(struct file *file, void 
*priv,
 static int mxt_vidioc_enum_input(struct file *file, void *priv,
   struct v4l2_input *i)
 {
-   if (i->index > 0)
+   if (i->index >= MXT_V4L_INPUT_MAX)
return -EINVAL;
 
i->type = V4L2_INPUT_TYPE_TOUCH;
-   strlcpy(i->name, "Mutual Capacitance Deltas", sizeof(i->name));
+
+   switch (i->index) {
+   case MXT_V4L_INPUT_REFS:
+   strlcpy(i->name, "Mutual Capacitance References",
+   sizeof(i->name));
+   break;
+   case MXT_V4L_INPUT_DELTAS:
+   strlcpy(i->name, "Mutual Capacitance Deltas", sizeof(i->name));
+   break;
+   }
+
return 0;
 }
 
@@ -2337,12 +2366,16 @@ static int mxt_set_input(struct mxt_data *data, 
unsigned int i)
 {
struct v4l2_pix_format *f = >dbg.format;
 
-   if (i > 0)
+   if (i >= MXT_V4L_INPUT_MAX)
return -EINVAL;
 
+   if (i == MXT_V4L_INPUT_DELTAS)
+   f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
+   else
+   f->pixelformat = V4L2_TCH_FMT_TU16;
+
f->width = data->xy_switch ? data->ysize : data->xsize;
f->height = data->xy_switch ? data->xsize : data->ysize;
-   f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
f->bytesperline = f->width * sizeof(u16);
@@ -2383,7 +2416,19 @@ static int mxt_vidioc_enum_fmt(struct file *file, void 
*priv,
if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
 
-   fmt->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
+   switch (fmt->index) {
+   case 0:
+   fmt->pixelformat = V4L2_TCH_FMT_TU16;
+   break;
+
+   case 1:
+   fmt->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
+   break;
+
+   default:
+   return -EINVAL;
+   }
+
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 v7 02/11] v4l2-core: Add support for touch devices

2016-07-08 Thread Nick Dyer
Some touch controllers send out touch data in a similar way to a
greyscale frame grabber.

Add new device type VFL_TYPE_TOUCH:
- This uses a new device prefix v4l-touch for these devices, to stop
  generic capture software from treating them as webcams. Otherwise,
  touch is treated similarly to video capture.
- Add V4L2_INPUT_TYPE_TOUCH
- Add MEDIA_INTF_T_V4L_TOUCH
- Add V4L2_CAP_TOUCH to indicate device is a touch device

Add formats:
- V4L2_TCH_FMT_DELTA_TD16 for signed 16-bit touch deltas
- V4L2_TCH_FMT_DELTA_TD08 for signed 16-bit touch deltas
- V4L2_TCH_FMT_TU16 for unsigned 16-bit touch data
- V4L2_TCH_FMT_TU08 for unsigned 8-bit touch data

This support will be used by:
- Atmel maXTouch (atmel_mxt_ts)
- Synaptics RMI4.
- sur40

Signed-off-by: Nick Dyer <n...@shmanahar.org>
Tested-By: Chris Healy <cphe...@gmail.com>
---
 drivers/media/media-entity.c |2 ++
 drivers/media/v4l2-core/v4l2-dev.c   |   16 ---
 drivers/media/v4l2-core/v4l2-ioctl.c |   36 +-
 include/media/v4l2-dev.h |3 ++-
 include/uapi/linux/media.h   |1 +
 include/uapi/linux/videodev2.h   |9 +
 6 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index d8a2299..9014362 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -65,6 +65,8 @@ static inline const char *intf_type(struct media_interface 
*intf)
return "v4l-subdev";
case MEDIA_INTF_T_V4L_SWRADIO:
return "v4l-swradio";
+   case MEDIA_INTF_T_V4L_TOUCH:
+   return "v4l-touch";
case MEDIA_INTF_T_ALSA_PCM_CAPTURE:
return "alsa-pcm-capture";
case MEDIA_INTF_T_ALSA_PCM_PLAYBACK:
diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index 70b559d..21ba9b4 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -527,6 +527,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI;
bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO;
bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR;
+   bool is_tch = vdev->vfl_type == VFL_TYPE_TOUCH;
bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
 
@@ -573,7 +574,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
if (ops->vidioc_enum_freq_bands || ops->vidioc_g_tuner || 
ops->vidioc_g_modulator)
set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls);
 
-   if (is_vid) {
+   if (is_vid || is_tch) {
/* video specific ioctls */
if ((is_rx && (ops->vidioc_enum_fmt_vid_cap ||
   ops->vidioc_enum_fmt_vid_cap_mplane ||
@@ -662,7 +663,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
}
 
-   if (is_vid || is_vbi || is_sdr) {
+   if (is_vid || is_vbi || is_sdr || is_tch) {
/* ioctls valid for video, vbi or sdr */
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
@@ -675,7 +676,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
}
 
-   if (is_vid || is_vbi) {
+   if (is_vid || is_vbi || is_tch) {
/* ioctls valid for video or vbi */
if (ops->vidioc_s_std)
set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
@@ -751,6 +752,10 @@ static int video_register_media_controller(struct 
video_device *vdev, int type)
intf_type = MEDIA_INTF_T_V4L_SWRADIO;
vdev->entity.function = MEDIA_ENT_F_IO_SWRADIO;
break;
+   case VFL_TYPE_TOUCH:
+   intf_type = MEDIA_INTF_T_V4L_TOUCH;
+   vdev->entity.function = MEDIA_ENT_F_IO_V4L;
+   break;
case VFL_TYPE_RADIO:
intf_type = MEDIA_INTF_T_V4L_RADIO;
/*
@@ -845,6 +850,8 @@ static int video_register_media_controller(struct 
video_device *vdev, int type)
  * %VFL_TYPE_SUBDEV - A subdevice
  *
  * %VFL_TYPE_SDR - Software Defined Radio
+ *
+ * %VFL_TYPE_TOUCH - A touch sensor
  */
 int __video_register_device(struct video_device *vdev, int type, int nr,
int warn_if_nr_in_use, struct module *owner)
@@ -888,6 +895,9 @@ int __video_register_device(struct video_device *vdev, int 
type, int nr,
/* Use device name 'swradio' because 'sdr' was already taken. */
name_base = "swradio";
bre

Re: [PATCH v6 10/11] Input: synaptics-rmi4 - add support for F54 diagnostics

2016-07-01 Thread Nick Dyer
On Thu, Jun 30, 2016 at 06:38:53PM +0100, Nick Dyer wrote:
> Function 54 implements access to various RMI4 diagnostic features.
> 
> This patch adds support for retrieving this data. It registers a V4L2
> device to output the data to user space.
> 
> Signed-off-by: Nick Dyer <n...@shmanahar.org>
> ---
>  drivers/input/rmi4/Kconfig  |  11 +
>  drivers/input/rmi4/Makefile |   1 +
>  drivers/input/rmi4/rmi_bus.c|   3 +
>  drivers/input/rmi4/rmi_driver.h |   1 +
>  drivers/input/rmi4/rmi_f54.c| 754 
> 
>  5 files changed, 770 insertions(+)
>  create mode 100644 drivers/input/rmi4/rmi_f54.c
[...]
> index 000..2361157
> --- /dev/null
> +++ b/drivers/input/rmi4/rmi_f54.c
[...]
> +static int rmi_f54_vidioc_querycap(struct file *file, void *priv,
> +struct v4l2_capability *cap)
> +{
> + struct f54_data *f54 = video_drvdata(file);
> +
> + strlcpy(cap->driver, F54_NAME, sizeof(cap->driver));
> + strlcpy(cap->card, SYNAPTICS_INPUT_DEVICE_NAME, sizeof(cap->card));
> + strlcpy(cap->bus_info, dev_name(>fn->dev), sizeof(cap->bus_info));

I need to correct this to prefix the bus. RMI4 registers its own bus, so
devices appear under eg /sys/bus/rmi4/devices/rmi4-00.fn54

So I will change to:
snprintf(cap->bus_info, sizeof(cap->bus_info), "rmi4:%s", 
dev_name(>fn->dev));

And I will need to add rmi4 to the valid prefixes in v4l2-complaince as well.

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


[PATCH v6 06/11] Input: atmel_mxt_ts - read touchscreen size

2016-06-30 Thread Nick Dyer
The touchscreen may have a margin where not all the matrix is used. Read
the parameters from T9 and T100 and take account of the difference.

Note: this does not read the XORIGIN/YORIGIN fields so it assumes that
the touchscreen starts at (0,0)

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 42 +++-
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index bea95a1..d09ecc3 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -103,6 +103,8 @@ struct t7_config {
 
 /* MXT_TOUCH_MULTI_T9 field */
 #define MXT_T9_CTRL0
+#define MXT_T9_XSIZE   3
+#define MXT_T9_YSIZE   4
 #define MXT_T9_ORIENT  9
 #define MXT_T9_RANGE   18
 
@@ -150,7 +152,9 @@ struct t37_debug {
 #define MXT_T100_CTRL  0
 #define MXT_T100_CFG1  1
 #define MXT_T100_TCHAUX3
+#define MXT_T100_XSIZE 9
 #define MXT_T100_XRANGE13
+#define MXT_T100_YSIZE 20
 #define MXT_T100_YRANGE24
 
 #define MXT_T100_CFG_SWITCHXY  BIT(5)
@@ -259,6 +263,8 @@ struct mxt_data {
unsigned int max_x;
unsigned int max_y;
bool xy_switch;
+   u8 xsize;
+   u8 ysize;
bool in_bootloader;
u16 mem_size;
u8 t100_aux_ampl;
@@ -1714,6 +1720,18 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return -EINVAL;
 
error = __mxt_read_reg(client,
+  object->start_address + MXT_T9_XSIZE,
+  sizeof(data->xsize), >xsize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T9_YSIZE,
+  sizeof(data->ysize), >ysize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
   object->start_address + MXT_T9_RANGE,
   sizeof(range), );
if (error)
@@ -1763,6 +1781,18 @@ static int mxt_read_t100_config(struct mxt_data *data)
 
data->max_y = get_unaligned_le16(_y);
 
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T100_XSIZE,
+  sizeof(data->xsize), >xsize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T100_YSIZE,
+  sizeof(data->ysize), >ysize);
+   if (error)
+   return error;
+
/* read orientation config */
error =  __mxt_read_reg(client,
object->start_address + MXT_T100_CFG1,
@@ -2121,7 +2151,7 @@ static int mxt_convert_debug_pages(struct mxt_data *data, 
u16 *outbuf)
outbuf[i] = mxt_get_debug_value(data, x, y);
 
/* Next value */
-   if (++x >= data->info.matrix_xsize) {
+   if (++x >= data->xsize) {
x = 0;
y++;
}
@@ -2276,8 +2306,8 @@ static int mxt_set_input(struct mxt_data *data, unsigned 
int i)
if (i > 0)
return -EINVAL;
 
-   f->width = data->info.matrix_xsize;
-   f->height = data->info.matrix_ysize;
+   f->width = data->xsize;
+   f->height = data->ysize;
f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
@@ -2392,9 +2422,9 @@ static void mxt_debug_init(struct mxt_data *data)
dbg->t37_address = object->start_address;
 
/* Calculate size of data and allocate buffer */
-   dbg->t37_nodes = data->info.matrix_xsize * data->info.matrix_ysize;
-   dbg->t37_pages = DIV_ROUND_UP(dbg->t37_nodes * sizeof(u16),
- sizeof(dbg->t37_buf->data));
+   dbg->t37_nodes = data->xsize * data->ysize;
+   dbg->t37_pages = DIV_ROUND_UP(data->xsize * data->info.matrix_ysize *
+ sizeof(u16), sizeof(dbg->t37_buf->data));
 
dbg->t37_buf = devm_kmalloc_array(>client->dev, dbg->t37_pages,
  sizeof(struct t37_debug), GFP_KERNEL);
-- 
2.5.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


[PATCH v6 10/11] Input: synaptics-rmi4 - add support for F54 diagnostics

2016-06-30 Thread Nick Dyer
Function 54 implements access to various RMI4 diagnostic features.

This patch adds support for retrieving this data. It registers a V4L2
device to output the data to user space.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/rmi4/Kconfig  |  11 +
 drivers/input/rmi4/Makefile |   1 +
 drivers/input/rmi4/rmi_bus.c|   3 +
 drivers/input/rmi4/rmi_driver.h |   1 +
 drivers/input/rmi4/rmi_f54.c| 754 
 5 files changed, 770 insertions(+)
 create mode 100644 drivers/input/rmi4/rmi_f54.c

diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
index f73df24..f3418b6 100644
--- a/drivers/input/rmi4/Kconfig
+++ b/drivers/input/rmi4/Kconfig
@@ -61,3 +61,14 @@ config RMI4_F30
 
  Function 30 provides GPIO and LED support for RMI4 devices. This
  includes support for buttons on TouchPads and ClickPads.
+
+config RMI4_F54
+   bool "RMI4 Function 54 (Analog diagnostics)"
+   depends on RMI4_CORE
+   depends on VIDEO_V4L2
+   select VIDEOBUF2_VMALLOC
+   help
+ Say Y here if you want to add support for RMI4 function 54
+
+ Function 54 provides access to various diagnostic features in certain
+ RMI4 touch sensors.
diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index 95c00a7..0bafc85 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -7,6 +7,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
+rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 
 # Transports
 obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o
diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index b368b05..3aedc65 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -315,6 +315,9 @@ static struct rmi_function_handler *fn_handlers[] = {
 #ifdef CONFIG_RMI4_F30
_f30_handler,
 #endif
+#ifdef CONFIG_RMI4_F54
+   _f54_handler,
+#endif
 };
 
 static void __rmi_unregister_function_handlers(int start_idx)
diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
index 6e140fa..8dfbebe 100644
--- a/drivers/input/rmi4/rmi_driver.h
+++ b/drivers/input/rmi4/rmi_driver.h
@@ -102,4 +102,5 @@ extern struct rmi_function_handler rmi_f01_handler;
 extern struct rmi_function_handler rmi_f11_handler;
 extern struct rmi_function_handler rmi_f12_handler;
 extern struct rmi_function_handler rmi_f30_handler;
+extern struct rmi_function_handler rmi_f54_handler;
 #endif
diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c
new file mode 100644
index 000..2361157
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f54.c
@@ -0,0 +1,754 @@
+/*
+ * Copyright (c) 2012-2015 Synaptics Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "rmi_driver.h"
+
+#define F54_NAME   "rmi4_f54"
+
+/* F54 data offsets */
+#define F54_REPORT_DATA_OFFSET  3
+#define F54_FIFO_OFFSET 1
+#define F54_NUM_TX_OFFSET   1
+#define F54_NUM_RX_OFFSET   0
+
+/* F54 commands */
+#define F54_GET_REPORT  1
+#define F54_FORCE_CAL   2
+
+/* Fixed sizes of reports */
+#define F54_QUERY_LEN  27
+
+/* F54 capabilities */
+#define F54_CAP_BASELINE   (1 << 2)
+#define F54_CAP_IMAGE8 (1 << 3)
+#define F54_CAP_IMAGE16(1 << 6)
+
+/**
+ * enum rmi_f54_report_type - RMI4 F54 report types
+ *
+ * @F54_8BIT_IMAGE:Normalized 8-Bit Image Report. The capacitance variance
+ * from baseline for each pixel.
+ *
+ * @F54_16BIT_IMAGE:   Normalized 16-Bit Image Report. The capacitance variance
+ * from baseline for each pixel.
+ *
+ * @F54_RAW_16BIT_IMAGE:
+ * Raw 16-Bit Image Report. The raw capacitance for each
+ * pixel.
+ *
+ * @F54_TRUE_BASELINE: True Baseline Report. The baseline capacitance for each
+ * pixel.
+ *
+ * @F54_FULL_RAW_CAP:   Full Raw Capacitance Report. The raw capacitance with
+ * low reference set to its minimum value and high
+ * reference set to its maximum value.
+ *
+ * @F54_FULL_RAW_CAP_RX_OFFSET_REMOVED:
+ * Full Raw Capacitance with Receiver Offset Removed
+ * Report. Set Low reference to its minimum value and high
+ * references to its maximum value, then report the raw
+ * capacitance for each pixel.
+ */
+enum rmi_f54_report_type {
+   F54_REPORT_NONE = 0,
+

[PATCH v6 04/11] Input: atmel_mxt_ts - add support for T37 diagnostic data

2016-06-30 Thread Nick Dyer
Atmel maXTouch devices have a T37 object which can be used to read raw
touch deltas from the device. This consists of an array of 16-bit
integers, one for each node on the touchscreen matrix.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/Kconfig|   6 ++
 drivers/input/touchscreen/atmel_mxt_ts.c | 159 +++
 2 files changed, 165 insertions(+)

diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index 8ecdc38..da96ecf 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -115,6 +115,12 @@ config TOUCHSCREEN_ATMEL_MXT
  To compile this driver as a module, choose M here: the
  module will be called atmel_mxt_ts.
 
+config TOUCHSCREEN_ATMEL_MXT_T37
+   bool "Support T37 Diagnostic Data"
+   depends on TOUCHSCREEN_ATMEL_MXT
+   help
+ Say Y here if you want support for the T37 Diagnostic Data object.
+
 config TOUCHSCREEN_AUO_PIXCIR
tristate "AUO in-cell touchscreen using Pixcir ICs"
depends on I2C
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 5af7907..0048233 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -124,6 +124,19 @@ struct t9_range {
 #define MXT_COMMS_CTRL 0
 #define MXT_COMMS_CMD  1
 
+/* MXT_DEBUG_DIAGNOSTIC_T37 */
+#define MXT_DIAGNOSTIC_PAGEUP  0x01
+#define MXT_DIAGNOSTIC_DELTAS  0x10
+#define MXT_DIAGNOSTIC_SIZE128
+
+struct t37_debug {
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+   u8 mode;
+   u8 page;
+   u8 data[MXT_DIAGNOSTIC_SIZE];
+#endif
+};
+
 /* Define for MXT_GEN_COMMAND_T6 */
 #define MXT_BOOT_VALUE 0xa5
 #define MXT_RESET_VALUE0x01
@@ -205,6 +218,14 @@ struct mxt_object {
u8 num_report_ids;
 } __packed;
 
+struct mxt_dbg {
+   u16 t37_address;
+   u16 diag_cmd_address;
+   struct t37_debug *t37_buf;
+   unsigned int t37_pages;
+   unsigned int t37_nodes;
+};
+
 /* Each client has this additional data */
 struct mxt_data {
struct i2c_client *client;
@@ -233,6 +254,7 @@ struct mxt_data {
u8 num_touchids;
u8 multitouch;
struct t7_config t7_cfg;
+   struct mxt_dbg dbg;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -2043,6 +2065,141 @@ recheck:
return 0;
 }
 
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
+  unsigned int y)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int ofs, page;
+
+   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   page = ofs / MXT_DIAGNOSTIC_SIZE;
+   ofs %= MXT_DIAGNOSTIC_SIZE;
+
+   return get_unaligned_le16(>t37_buf[page].data[ofs]);
+}
+
+static int mxt_convert_debug_pages(struct mxt_data *data, u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int x = 0;
+   unsigned int y = 0;
+   unsigned int i;
+
+   for (i = 0; i < dbg->t37_nodes; i++) {
+   outbuf[i] = mxt_get_debug_value(data, x, y);
+
+   /* Next value */
+   if (++x >= data->info.matrix_xsize) {
+   x = 0;
+   y++;
+   }
+   }
+
+   return 0;
+}
+
+static int mxt_read_diagnostic_debug(struct mxt_data *data, u8 mode,
+u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   int retries = 0;
+   int page;
+   int ret;
+   u8 cmd = mode;
+   struct t37_debug *p;
+   u8 cmd_poll;
+
+   for (page = 0; page < dbg->t37_pages; page++) {
+   p = dbg->t37_buf + page;
+
+   ret = mxt_write_reg(data->client, dbg->diag_cmd_address,
+   cmd);
+   if (ret)
+   return ret;
+
+   retries = 0;
+   msleep(20);
+wait_cmd:
+   /* Read back command byte */
+   ret = __mxt_read_reg(data->client, dbg->diag_cmd_address,
+sizeof(cmd_poll), _poll);
+   if (ret)
+   return ret;
+
+   /* Field is cleared once the command has been processed */
+   if (cmd_poll) {
+   if (retries++ > 100)
+   return -EINVAL;
+
+   msleep(20);
+   goto wait_cmd;
+   }
+
+   /* Read T37 page */
+   ret = __mxt_read_reg(data->client, dbg->t37_address,
+sizeof(struct t37_debug), p);
+   if (ret)
+   return ret;
+
+   if (p->mode != mode || p->page != page) {
+  

[PATCH v6 01/11] Input: atmel_mxt_ts - update MAINTAINERS email address

2016-06-30 Thread Nick Dyer
I'm leaving ITDev, so change to my personal email. My understanding is
that someone at Atmel will take this on once their takeover by Microchip
has settled down.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 MAINTAINERS | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0f148d3..6affed5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2181,9 +2181,9 @@ S:Maintained
 F: drivers/net/wireless/atmel/atmel*
 
 ATMEL MAXTOUCH DRIVER
-M:     Nick Dyer <nick.d...@itdev.co.uk>
-T: git git://github.com/atmel-maxtouch/linux.git
-S: Supported
+M:     Nick Dyer <n...@shmanahar.org>
+T: git git://github.com/ndyer/linux.git
+S: Maintained
 F: Documentation/devicetree/bindings/input/atmel,maxtouch.txt
 F: drivers/input/touchscreen/atmel_mxt_ts.c
 F: include/linux/platform_data/atmel_mxt_ts.h
-- 
2.5.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


[PATCH v6 11/11] Input: sur40 - use new V4L2 touch input type

2016-06-30 Thread Nick Dyer
Support both V4L2_TCH_FMT_TU08 and V4L2_PIX_FMT_GREY for backwards
compatibility.

Note: I have not tested these changes (I have no access to the hardware)
so not signing off.
---
 drivers/input/touchscreen/sur40.c | 121 +++---
 1 file changed, 88 insertions(+), 33 deletions(-)

diff --git a/drivers/input/touchscreen/sur40.c 
b/drivers/input/touchscreen/sur40.c
index 880c40b..9ba68cf 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -139,6 +139,27 @@ struct sur40_image_header {
 #define SUR40_GET_STATE   0xc5 /*  4 bytes state (?) */
 #define SUR40_GET_SENSORS 0xb1 /*  8 bytes sensors   */
 
+static const struct v4l2_pix_format sur40_pix_format[] = {
+   {
+   .pixelformat = V4L2_TCH_FMT_TU08,
+   .width  = SENSOR_RES_X / 2,
+   .height = SENSOR_RES_Y / 2,
+   .field = V4L2_FIELD_NONE,
+   .colorspace = V4L2_COLORSPACE_SRGB,
+   .bytesperline = SENSOR_RES_X / 2,
+   .sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
+   },
+   {
+   .pixelformat = V4L2_PIX_FMT_GREY,
+   .width  = SENSOR_RES_X / 2,
+   .height = SENSOR_RES_Y / 2,
+   .field = V4L2_FIELD_NONE,
+   .colorspace = V4L2_COLORSPACE_SRGB,
+   .bytesperline = SENSOR_RES_X / 2,
+   .sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
+   }
+};
+
 /* master device state */
 struct sur40_state {
 
@@ -149,6 +170,7 @@ struct sur40_state {
struct v4l2_device v4l2;
struct video_device vdev;
struct mutex lock;
+   struct v4l2_pix_format pix_fmt;
 
struct vb2_queue queue;
struct vb2_alloc_ctx *alloc_ctx;
@@ -170,7 +192,6 @@ struct sur40_buffer {
 
 /* forward declarations */
 static const struct video_device sur40_video_device;
-static const struct v4l2_pix_format sur40_video_format;
 static const struct vb2_queue sur40_queue;
 static void sur40_process_video(struct sur40_state *sur40);
 
@@ -421,7 +442,7 @@ static void sur40_process_video(struct sur40_state *sur40)
goto err_poll;
}
 
-   if (le32_to_cpu(img->size) != sur40_video_format.sizeimage) {
+   if (le32_to_cpu(img->size) != sur40->pix_fmt.sizeimage) {
dev_err(sur40->dev, "image size mismatch\n");
goto err_poll;
}
@@ -432,7 +453,7 @@ static void sur40_process_video(struct sur40_state *sur40)
 
result = usb_sg_init(, sur40->usbdev,
usb_rcvbulkpipe(sur40->usbdev, VIDEO_ENDPOINT), 0,
-   sgt->sgl, sgt->nents, sur40_video_format.sizeimage, 0);
+   sgt->sgl, sgt->nents, sur40->pix_fmt.sizeimage, 0);
if (result < 0) {
dev_err(sur40->dev, "error %d in usb_sg_init\n", result);
goto err_poll;
@@ -593,13 +614,14 @@ static int sur40_probe(struct usb_interface *interface,
goto err_unreg_v4l2;
}
 
+   sur40->pix_fmt = sur40_pix_format[0];
sur40->vdev = sur40_video_device;
sur40->vdev.v4l2_dev = >v4l2;
sur40->vdev.lock = >lock;
sur40->vdev.queue = >queue;
video_set_drvdata(>vdev, sur40);
 
-   error = video_register_device(>vdev, VFL_TYPE_GRABBER, -1);
+   error = video_register_device(>vdev, VFL_TYPE_TOUCH, -1);
if (error) {
dev_err(>dev,
"Unable to register video subdevice.");
@@ -662,10 +684,10 @@ static int sur40_queue_setup(struct vb2_queue *q,
alloc_ctxs[0] = sur40->alloc_ctx;
 
if (*nplanes)
-   return sizes[0] < sur40_video_format.sizeimage ? -EINVAL : 0;
+   return sizes[0] < sur40->pix_fmt.sizeimage ? -EINVAL : 0;
 
*nplanes = 1;
-   sizes[0] = sur40_video_format.sizeimage;
+   sizes[0] = sur40->pix_fmt.sizeimage;
 
return 0;
 }
@@ -677,7 +699,7 @@ static int sur40_queue_setup(struct vb2_queue *q,
 static int sur40_buffer_prepare(struct vb2_buffer *vb)
 {
struct sur40_state *sur40 = vb2_get_drv_priv(vb->vb2_queue);
-   unsigned long size = sur40_video_format.sizeimage;
+   unsigned long size = sur40->pix_fmt.sizeimage;
 
if (vb2_plane_size(vb, 0) < size) {
dev_err(>usbdev->dev, "buffer too small (%lu < %lu)\n",
@@ -751,7 +773,7 @@ static int sur40_vidioc_querycap(struct file *file, void 
*priv,
strlcpy(cap->driver, DRIVER_SHORT, sizeof(cap->driver));
strlcpy(cap->card, DRIVER_LONG, sizeof(cap->card));
usb_make_path(sur40->usbdev, cap->bus_info, sizeof(cap->bus_info));
-   cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
+   cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TOUCH |
V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING;
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -763,7 +785,7 @@ static int sur40_vidioc_enum_input(struct file *file, void 

[PATCH v6 09/11] Input: atmel_mxt_ts - add support for reference data

2016-06-30 Thread Nick Dyer
There are different datatypes available from a maXTouch chip. Add
support to retrieve reference data as well.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 57 
 1 file changed, 51 insertions(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 7c4d937..f75f2ce 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -135,6 +135,7 @@ struct t9_range {
 /* MXT_DEBUG_DIAGNOSTIC_T37 */
 #define MXT_DIAGNOSTIC_PAGEUP  0x01
 #define MXT_DIAGNOSTIC_DELTAS  0x10
+#define MXT_DIAGNOSTIC_REFS0x11
 #define MXT_DIAGNOSTIC_SIZE128
 
 #define MXT_FAMILY_1386160
@@ -249,6 +250,12 @@ struct mxt_dbg {
int input;
 };
 
+enum v4l_dbg_inputs {
+   MXT_V4L_INPUT_DELTAS,
+   MXT_V4L_INPUT_REFS,
+   MXT_V4L_INPUT_MAX,
+};
+
 static const struct v4l2_file_operations mxt_video_fops = {
.owner = THIS_MODULE,
.open = v4l2_fh_open,
@@ -2273,6 +2280,7 @@ static void mxt_buffer_queue(struct vb2_buffer *vb)
struct mxt_data *data = vb2_get_drv_priv(vb->vb2_queue);
u16 *ptr;
int ret;
+   u8 mode;
 
ptr = vb2_plane_vaddr(vb, 0);
if (!ptr) {
@@ -2280,7 +2288,18 @@ static void mxt_buffer_queue(struct vb2_buffer *vb)
goto fault;
}
 
-   ret = mxt_read_diagnostic_debug(data, MXT_DIAGNOSTIC_DELTAS, ptr);
+   switch (data->dbg.input) {
+   case MXT_V4L_INPUT_DELTAS:
+   default:
+   mode = MXT_DIAGNOSTIC_DELTAS;
+   break;
+
+   case MXT_V4L_INPUT_REFS:
+   mode = MXT_DIAGNOSTIC_REFS;
+   break;
+   }
+
+   ret = mxt_read_diagnostic_debug(data, mode, ptr);
if (ret)
goto fault;
 
@@ -2325,11 +2344,21 @@ static int mxt_vidioc_querycap(struct file *file, void 
*priv,
 static int mxt_vidioc_enum_input(struct file *file, void *priv,
   struct v4l2_input *i)
 {
-   if (i->index > 0)
+   if (i->index >= MXT_V4L_INPUT_MAX)
return -EINVAL;
 
i->type = V4L2_INPUT_TYPE_TOUCH;
-   strlcpy(i->name, "Mutual Capacitance Deltas", sizeof(i->name));
+
+   switch (i->index) {
+   case MXT_V4L_INPUT_REFS:
+   strlcpy(i->name, "Mutual Capacitance References",
+   sizeof(i->name));
+   break;
+   case MXT_V4L_INPUT_DELTAS:
+   strlcpy(i->name, "Mutual Capacitance Deltas", sizeof(i->name));
+   break;
+   }
+
return 0;
 }
 
@@ -2337,12 +2366,16 @@ static int mxt_set_input(struct mxt_data *data, 
unsigned int i)
 {
struct v4l2_pix_format *f = >dbg.format;
 
-   if (i > 0)
+   if (i >= MXT_V4L_INPUT_MAX)
return -EINVAL;
 
+   if (i == MXT_V4L_INPUT_DELTAS)
+   f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
+   else
+   f->pixelformat = V4L2_TCH_FMT_TU16;
+
f->width = data->xy_switch ? data->ysize : data->xsize;
f->height = data->xy_switch ? data->xsize : data->ysize;
-   f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
f->bytesperline = f->width * sizeof(u16);
@@ -2383,7 +2416,19 @@ static int mxt_vidioc_enum_fmt(struct file *file, void 
*priv,
if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
 
-   fmt->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
+   switch (fmt->index) {
+   case 0:
+   fmt->pixelformat = V4L2_TCH_FMT_TU16;
+   break;
+
+   case 1:
+   fmt->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
+   break;
+
+   default:
+   return -EINVAL;
+   }
+
return 0;
 }
 
-- 
2.5.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


[PATCH v6 07/11] Input: atmel_mxt_ts - handle diagnostic data orientation

2016-06-30 Thread Nick Dyer
Invert the diagnostic data to match the orientation of the input device.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 26 +-
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index d09ecc3..c35fca0 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -125,6 +125,8 @@ struct t9_range {
 
 /* MXT_TOUCH_MULTI_T9 orient */
 #define MXT_T9_ORIENT_SWITCH   (1 << 0)
+#define MXT_T9_ORIENT_INVERTX  (1 << 1)
+#define MXT_T9_ORIENT_INVERTY  (1 << 2)
 
 /* MXT_SPT_COMMSCONFIG_T18 */
 #define MXT_COMMS_CTRL 0
@@ -158,6 +160,8 @@ struct t37_debug {
 #define MXT_T100_YRANGE24
 
 #define MXT_T100_CFG_SWITCHXY  BIT(5)
+#define MXT_T100_CFG_INVERTY   BIT(6)
+#define MXT_T100_CFG_INVERTX   BIT(7)
 
 #define MXT_T100_TCHAUX_VECT   BIT(0)
 #define MXT_T100_TCHAUX_AMPL   BIT(1)
@@ -262,6 +266,8 @@ struct mxt_data {
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
+   bool invertx;
+   bool inverty;
bool xy_switch;
u8 xsize;
u8 ysize;
@@ -1747,6 +1753,8 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return error;
 
data->xy_switch = orient & MXT_T9_ORIENT_SWITCH;
+   data->invertx = orient & MXT_T9_ORIENT_INVERTX;
+   data->inverty = orient & MXT_T9_ORIENT_INVERTY;
 
return 0;
 }
@@ -1801,6 +1809,8 @@ static int mxt_read_t100_config(struct mxt_data *data)
return error;
 
data->xy_switch = cfg & MXT_T100_CFG_SWITCHXY;
+   data->invertx = cfg & MXT_T100_CFG_INVERTX;
+   data->inverty = cfg & MXT_T100_CFG_INVERTY;
 
/* allocate aux bytes */
error =  __mxt_read_reg(client,
@@ -2145,13 +2155,19 @@ static int mxt_convert_debug_pages(struct mxt_data 
*data, u16 *outbuf)
struct mxt_dbg *dbg = >dbg;
unsigned int x = 0;
unsigned int y = 0;
-   unsigned int i;
+   unsigned int i, rx, ry;
 
for (i = 0; i < dbg->t37_nodes; i++) {
-   outbuf[i] = mxt_get_debug_value(data, x, y);
+   /* Handle orientation */
+   rx = data->xy_switch ? y : x;
+   ry = data->xy_switch ? x : y;
+   rx = data->invertx ? (data->xsize - 1 - rx) : rx;
+   ry = data->inverty ? (data->ysize - 1 - ry) : ry;
+
+   outbuf[i] = mxt_get_debug_value(data, rx, ry);
 
/* Next value */
-   if (++x >= data->xsize) {
+   if (++x >= (data->xy_switch ? data->ysize : data->xsize)) {
x = 0;
y++;
}
@@ -2306,8 +2322,8 @@ static int mxt_set_input(struct mxt_data *data, unsigned 
int i)
if (i > 0)
return -EINVAL;
 
-   f->width = data->xsize;
-   f->height = data->ysize;
+   f->width = data->xy_switch ? data->ysize : data->xsize;
+   f->height = data->xy_switch ? data->xsize : data->ysize;
f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
-- 
2.5.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


[PATCH v6 03/11] [media] DocBook: add support for touch devices

2016-06-30 Thread Nick Dyer
Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 Documentation/DocBook/media/v4l/dev-touch.xml  | 51 ++
 Documentation/DocBook/media/v4l/media-types.xml|  5 ++
 .../DocBook/media/v4l/pixfmt-tch-td08.xml  | 66 +
 .../DocBook/media/v4l/pixfmt-tch-td16.xml  | 82 ++
 .../DocBook/media/v4l/pixfmt-tch-tu08.xml  | 66 +
 .../DocBook/media/v4l/pixfmt-tch-tu16.xml  | 81 +
 Documentation/DocBook/media/v4l/pixfmt.xml | 13 
 Documentation/DocBook/media/v4l/v4l2.xml   |  1 +
 8 files changed, 365 insertions(+)
 create mode 100644 Documentation/DocBook/media/v4l/dev-touch.xml
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-tch-td08.xml
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-tch-td16.xml
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-tch-tu08.xml
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-tch-tu16.xml

diff --git a/Documentation/DocBook/media/v4l/dev-touch.xml 
b/Documentation/DocBook/media/v4l/dev-touch.xml
new file mode 100644
index 000..85d492a
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/dev-touch.xml
@@ -0,0 +1,51 @@
+Touch Devices
+
+Touch devices are accessed through character device special files
+  named /dev/v4l-touch0 to
+  /dev/v4l-touch255 with major number 81 and
+  dynamically allocated minor numbers 0 to 255.
+
+
+  Overview
+
+  Sensors may be Optical, or Projected Capacitive touch (PCT).
+
+  Processing is required to analyse the raw data and produce input
+events. In some systems, this may be performed on the ASIC and the raw data
+is purely a side-channel for diagnostics or tuning. In other systems, the
+ASIC is a simple analogue front end device which delivers touch data at
+high rate, and any touch processing must be done on the host.
+
+  For capacitive touch sensing, the touchscreen is composed of an array
+of horizontal and vertical conductors (alternatively called rows/columns,
+X/Y lines, or tx/rx). Mutual Capacitance measured is at the nodes where the
+conductors cross. Alternatively, Self Capacitance measures the signal from
+each column and row independently.
+
+  A touch input may be determined by comparing the raw capacitance
+measurement to a no-touch reference (or "baseline") measurement:
+
+  Delta = Raw - Reference
+
+  The reference measurement takes account of variations in the
+capacitance across the touch sensor matrix, for example
+manufacturing irregularities, environmental or edge effects.
+
+
+
+  Querying Capabilities
+
+  Devices supporting the touch interface set the
+V4L2_CAP_VIDEO_CAPTURE flag in the
+capabilities field of 
+returned by the  ioctl.
+
+  At least one of the read/write or streaming I/O methods must be
+supported.
+
+
+
+  Data Format Negotiation
+
+  A touch device may support any I/O method.
+
diff --git a/Documentation/DocBook/media/v4l/media-types.xml 
b/Documentation/DocBook/media/v4l/media-types.xml
index 5e3f20f..fb957c7 100644
--- a/Documentation/DocBook/media/v4l/media-types.xml
+++ b/Documentation/DocBook/media/v4l/media-types.xml
@@ -202,6 +202,11 @@
typically, /dev/swradio?
  
  
+   MEDIA_INTF_T_V4L_TOUCH
+   Device node interface for Touch device (V4L)
+   typically, /dev/v4l-touch?
+ 
+ 
MEDIA_INTF_T_ALSA_PCM_CAPTURE
Device node interface for ALSA PCM Capture
typically, /dev/snd/pcmC?D?c
diff --git a/Documentation/DocBook/media/v4l/pixfmt-tch-td08.xml 
b/Documentation/DocBook/media/v4l/pixfmt-tch-td08.xml
new file mode 100644
index 000..2483eb0
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/pixfmt-tch-td08.xml
@@ -0,0 +1,66 @@
+
+  
+V4L2_TCH_FMT_DELTA_TD08 ('TD08')
+
+  
+  
+V4L2_TCH_FMT_DELTA_TD08
+8-bit signed Touch Delta
+  
+  
+Description
+
+This format represents delta data from a touch controller
+
+Delta values may range from -128 to 127. Typically the values
+  will vary through a small range depending on whether the sensor is
+  touched or not. The full value may be seen if one of the
+  touchscreen nodes has a fault or the line is not connected.
+
+
+  V4L2_TCH_FMT_DELTA_TD08 4  4
+node matrix
+
+  
+Byte Order.
+Each cell is one byte.
+  
+
+  
+  
+
+  start+0:
+  D'00
+  D'01
+  D'02
+  D'03
+
+
+  start+4:
+  D'10
+  D'11
+  D'12
+  D'13
+
+
+  start+8:
+  D'20
+  D'21
+  D'22
+  

[PATCH v6 08/11] Input: atmel_mxt_ts - add diagnostic data support for mXT1386

2016-06-30 Thread Nick Dyer
The mXT1386 family of chips have a different architecture which splits
the diagnostic data into 3 columns.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 31 ---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index c35fca0..7c4d937 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -137,6 +137,10 @@ struct t9_range {
 #define MXT_DIAGNOSTIC_DELTAS  0x10
 #define MXT_DIAGNOSTIC_SIZE128
 
+#define MXT_FAMILY_1386160
+#define MXT1386_COLUMNS3
+#define MXT1386_PAGES_PER_COLUMN   8
+
 struct t37_debug {
 #ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
u8 mode;
@@ -2140,13 +2144,27 @@ recheck:
 static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
   unsigned int y)
 {
+   struct mxt_info *info = >info;
struct mxt_dbg *dbg = >dbg;
unsigned int ofs, page;
+   unsigned int col = 0;
+   unsigned int col_width;
+
+   if (info->family_id == MXT_FAMILY_1386) {
+   col_width = info->matrix_ysize / MXT1386_COLUMNS;
+   col = y / col_width;
+   y = y % col_width;
+   } else {
+   col_width = info->matrix_ysize;
+   }
 
-   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   ofs = (y + (x * col_width)) * sizeof(u16);
page = ofs / MXT_DIAGNOSTIC_SIZE;
ofs %= MXT_DIAGNOSTIC_SIZE;
 
+   if (info->family_id == MXT_FAMILY_1386)
+   page += col * MXT1386_PAGES_PER_COLUMN;
+
return get_unaligned_le16(>t37_buf[page].data[ofs]);
 }
 
@@ -2416,6 +2434,7 @@ static const struct video_device mxt_video_device = {
 
 static void mxt_debug_init(struct mxt_data *data)
 {
+   struct mxt_info *info = >info;
struct mxt_dbg *dbg = >dbg;
struct mxt_object *object;
int error;
@@ -2439,8 +2458,14 @@ static void mxt_debug_init(struct mxt_data *data)
 
/* Calculate size of data and allocate buffer */
dbg->t37_nodes = data->xsize * data->ysize;
-   dbg->t37_pages = DIV_ROUND_UP(data->xsize * data->info.matrix_ysize *
- sizeof(u16), sizeof(dbg->t37_buf->data));
+
+   if (info->family_id == MXT_FAMILY_1386)
+   dbg->t37_pages = MXT1386_COLUMNS * MXT1386_PAGES_PER_COLUMN;
+   else
+   dbg->t37_pages = DIV_ROUND_UP(data->xsize *
+ data->info.matrix_ysize *
+ sizeof(u16),
+ sizeof(dbg->t37_buf->data));
 
dbg->t37_buf = devm_kmalloc_array(>client->dev, dbg->t37_pages,
  sizeof(struct t37_debug), GFP_KERNEL);
-- 
2.5.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


[PATCH v6 0/11] Output raw touch data via V4L2

2016-06-30 Thread Nick Dyer
This is a series of patches to add output of raw touch diagnostic data via V4L2
to the Atmel maXTouch and Synaptics RMI4 drivers.

It's a rewrite of the previous implementation which output via debugfs: it now
uses a V4L2 device in a similar way to the sur40 driver.

We have a utility which can read the data and display it in a useful format:
https://github.com/ndyer/heatmap/commits/heatmap-v4l

These patches are also available from
https://github.com/ndyer/linux/commits/v4l-touch-2016-06-30

I will also send a patch to update v4l2-compliance.

Changes in v6:
- Remove BUF_TYPE_TOUCH_CAPTURE, as discussed with Hans V touch devices will
  use BUF_TYPE_VIDEO_CAPTURE.
- Touch devices should now register CAP_VIDEO_CAPTURE: CAP_TOUCH just says that
  this is a touch device, not a video device, but otherwise it acts the same.
- Add some code to v4l_s_fmt() to set sensible default values for fields not
  used by touch.
- Improve naming/doc of RMI4 F54 report types.
- Various minor DocBook fixes, and split to separate patch.
- Update my email address.
- Rework sur40 changes so that PIX_FMT_GREY is supported for backward
  compatibility. Florian is it possible for you to test?

Changes in v5 (Hans Verkuil review):
- Update v4l2-core:
  - Add VFL_TYPE_TOUCH, V4L2_BUF_TYPE_TOUCH_CAPTURE and V4L2_CAP_TOUCH
  - Change V4L2_INPUT_TYPE_TOUCH_SENSOR to V4L2_INPUT_TYPE_TOUCH
  - Improve DocBook documentation
  - Add FMT definitions for touch data
  - Note this will need the latest version of the heatmap util
- Synaptics RMI4 driver:
  - Remove some less important non full frame report types
  - Switch report type names to const char * array
  - Move a static array to inside context struct
- Split sur40 changes to a separate commit

Changes in v4:
- Address nits from the input side in atmel_mxt_ts patches (Dmitry Torokhov)
- Add Synaptics RMI4 F54 support patch

Changes in v3:
- Address V4L2 review comments from Hans Verkuil
- Run v4l-compliance and fix all issues - needs minor patch here:
  https://github.com/ndyer/v4l-utils/commit/cf50469773f

Changes in v2:
- Split pixfmt changes into separate commit and add DocBook
- Introduce VFL_TYPE_TOUCH_SENSOR and /dev/v4l-touch
- Remove "single node" support for now, it may be better to treat it as
  metadata later
- Explicitly set VFL_DIR_RX
- Fix Kconfig

--
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 v6 05/11] Input: atmel_mxt_ts - output diagnostic debug via V4L2 device

2016-06-30 Thread Nick Dyer
Register a video device to output T37 diagnostic data.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/input/touchscreen/Kconfig|   6 +-
 drivers/input/touchscreen/atmel_mxt_ts.c | 244 +++
 2 files changed, 248 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index da96ecf..7c1c5ec 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -117,9 +117,11 @@ config TOUCHSCREEN_ATMEL_MXT
 
 config TOUCHSCREEN_ATMEL_MXT_T37
bool "Support T37 Diagnostic Data"
-   depends on TOUCHSCREEN_ATMEL_MXT
+   depends on TOUCHSCREEN_ATMEL_MXT && VIDEO_V4L2
+   select VIDEOBUF2_VMALLOC
help
- Say Y here if you want support for the T37 Diagnostic Data object.
+ Say Y here if you want support to output data from the T37
+ Diagnostic Data object using a V4L device.
 
 config TOUCHSCREEN_AUO_PIXCIR
tristate "AUO in-cell touchscreen using Pixcir ICs"
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 0048233..bea95a1 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -28,6 +28,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 /* Firmware files */
 #define MXT_FW_NAME"maxtouch.fw"
@@ -224,6 +228,23 @@ struct mxt_dbg {
struct t37_debug *t37_buf;
unsigned int t37_pages;
unsigned int t37_nodes;
+
+   struct v4l2_device v4l2;
+   struct v4l2_pix_format format;
+   struct video_device vdev;
+   struct vb2_queue queue;
+   struct mutex lock;
+   int input;
+};
+
+static const struct v4l2_file_operations mxt_video_fops = {
+   .owner = THIS_MODULE,
+   .open = v4l2_fh_open,
+   .release = vb2_fop_release,
+   .unlocked_ioctl = video_ioctl2,
+   .read = vb2_fop_read,
+   .mmap = vb2_fop_mmap,
+   .poll = vb2_fop_poll,
 };
 
 /* Each client has this additional data */
@@ -279,6 +300,11 @@ struct mxt_data {
struct completion crc_completion;
 };
 
+struct mxt_vb2_buffer {
+   struct vb2_buffer   vb;
+   struct list_headlist;
+};
+
 static size_t mxt_obj_size(const struct mxt_object *obj)
 {
return obj->size_minus_one + 1;
@@ -1525,6 +1551,11 @@ static void mxt_free_input_device(struct mxt_data *data)
 
 static void mxt_free_object_table(struct mxt_data *data)
 {
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+   video_unregister_device(>dbg.vdev);
+   v4l2_device_unregister(>dbg.v4l2);
+#endif
+
kfree(data->object_table);
data->object_table = NULL;
kfree(data->msg_buf);
@@ -2157,10 +2188,191 @@ wait_cmd:
return mxt_convert_debug_pages(data, outbuf);
 }
 
+static int mxt_queue_setup(struct vb2_queue *q,
+  unsigned int *nbuffers, unsigned int *nplanes,
+  unsigned int sizes[], void *alloc_ctxs[])
+{
+   struct mxt_data *data = q->drv_priv;
+   size_t size = data->dbg.t37_nodes * sizeof(u16);
+
+   if (*nplanes)
+   return sizes[0] < size ? -EINVAL : 0;
+
+   *nplanes = 1;
+   sizes[0] = size;
+
+   return 0;
+}
+
+static void mxt_buffer_queue(struct vb2_buffer *vb)
+{
+   struct mxt_data *data = vb2_get_drv_priv(vb->vb2_queue);
+   u16 *ptr;
+   int ret;
+
+   ptr = vb2_plane_vaddr(vb, 0);
+   if (!ptr) {
+   dev_err(>client->dev, "Error acquiring frame ptr\n");
+   goto fault;
+   }
+
+   ret = mxt_read_diagnostic_debug(data, MXT_DIAGNOSTIC_DELTAS, ptr);
+   if (ret)
+   goto fault;
+
+   vb2_set_plane_payload(vb, 0, data->dbg.t37_nodes * sizeof(u16));
+   vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+   return;
+
+fault:
+   vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+}
+
+/* V4L2 structures */
+static const struct vb2_ops mxt_queue_ops = {
+   .queue_setup= mxt_queue_setup,
+   .buf_queue  = mxt_buffer_queue,
+   .wait_prepare   = vb2_ops_wait_prepare,
+   .wait_finish= vb2_ops_wait_finish,
+};
+
+static const struct vb2_queue mxt_queue = {
+   .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+   .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ,
+   .buf_struct_size = sizeof(struct mxt_vb2_buffer),
+   .ops = _queue_ops,
+   .mem_ops = _vmalloc_memops,
+   .timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC,
+   .min_buffers_needed = 1,
+};
+
+static int mxt_vidioc_querycap(struct file *file, void *priv,
+struct v4l2_capability *cap)
+{
+   struct mxt_data *data = video_drvdata(file);
+
+   strlcpy(cap->driver, "atmel_mxt_ts", sizeof(cap->driver));
+ 

[PATCH v6 02/11] [media] v4l2-core: Add support for touch devices

2016-06-30 Thread Nick Dyer
Some touch controllers send out touch data in a similar way to a
greyscale frame grabber.

Add new device type VFL_TYPE_TOUCH:
- This uses a new device prefix v4l-touch for these devices, to stop
  generic capture software from treating them as webcams. Otherwise,
  touch is treated similarly to video capture.
- Add V4L2_INPUT_TYPE_TOUCH
- Add MEDIA_INTF_T_V4L_TOUCH
- Add V4L2_CAP_TOUCH to indicate device is a touch device

Add formats:
- V4L2_TCH_FMT_DELTA_TD16 for signed 16-bit touch deltas
- V4L2_TCH_FMT_DELTA_TD08 for signed 16-bit touch deltas
- V4L2_TCH_FMT_TU16 for unsigned 16-bit touch data
- V4L2_TCH_FMT_TU08 for unsigned 8-bit touch data

This support will be used by:
- Atmel maXTouch (atmel_mxt_ts)
- Synaptics RMI4.
- sur40

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 drivers/media/media-entity.c |  2 ++
 drivers/media/v4l2-core/v4l2-dev.c   | 16 +---
 drivers/media/v4l2-core/v4l2-ioctl.c | 36 +++-
 include/media/v4l2-dev.h |  3 ++-
 include/uapi/linux/media.h   |  1 +
 include/uapi/linux/videodev2.h   |  9 +
 6 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index d8a2299..9014362 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -65,6 +65,8 @@ static inline const char *intf_type(struct media_interface 
*intf)
return "v4l-subdev";
case MEDIA_INTF_T_V4L_SWRADIO:
return "v4l-swradio";
+   case MEDIA_INTF_T_V4L_TOUCH:
+   return "v4l-touch";
case MEDIA_INTF_T_ALSA_PCM_CAPTURE:
return "alsa-pcm-capture";
case MEDIA_INTF_T_ALSA_PCM_PLAYBACK:
diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index 70b559d..21ba9b4 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -527,6 +527,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI;
bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO;
bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR;
+   bool is_tch = vdev->vfl_type == VFL_TYPE_TOUCH;
bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
 
@@ -573,7 +574,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
if (ops->vidioc_enum_freq_bands || ops->vidioc_g_tuner || 
ops->vidioc_g_modulator)
set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls);
 
-   if (is_vid) {
+   if (is_vid || is_tch) {
/* video specific ioctls */
if ((is_rx && (ops->vidioc_enum_fmt_vid_cap ||
   ops->vidioc_enum_fmt_vid_cap_mplane ||
@@ -662,7 +663,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
}
 
-   if (is_vid || is_vbi || is_sdr) {
+   if (is_vid || is_vbi || is_sdr || is_tch) {
/* ioctls valid for video, vbi or sdr */
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
@@ -675,7 +676,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
}
 
-   if (is_vid || is_vbi) {
+   if (is_vid || is_vbi || is_tch) {
/* ioctls valid for video or vbi */
if (ops->vidioc_s_std)
set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
@@ -751,6 +752,10 @@ static int video_register_media_controller(struct 
video_device *vdev, int type)
intf_type = MEDIA_INTF_T_V4L_SWRADIO;
vdev->entity.function = MEDIA_ENT_F_IO_SWRADIO;
break;
+   case VFL_TYPE_TOUCH:
+   intf_type = MEDIA_INTF_T_V4L_TOUCH;
+   vdev->entity.function = MEDIA_ENT_F_IO_V4L;
+   break;
case VFL_TYPE_RADIO:
intf_type = MEDIA_INTF_T_V4L_RADIO;
/*
@@ -845,6 +850,8 @@ static int video_register_media_controller(struct 
video_device *vdev, int type)
  * %VFL_TYPE_SUBDEV - A subdevice
  *
  * %VFL_TYPE_SDR - Software Defined Radio
+ *
+ * %VFL_TYPE_TOUCH - A touch sensor
  */
 int __video_register_device(struct video_device *vdev, int type, int nr,
int warn_if_nr_in_use, struct module *owner)
@@ -888,6 +895,9 @@ int __video_register_device(struct video_device *vdev, int 
type, int nr,
/* Use device name 'swradio' because 'sdr' was already taken. */
name_base = "swradio";
break;
+   case VFL_TYPE_TOUCH:
+   name_base = "v

[PATCH] v4l2-compliance: Changes to support touch sensors

2016-06-30 Thread Nick Dyer
Signed-off-by: Nick Dyer <n...@shmanahar.org>
---
 utils/v4l2-compliance/v4l2-compliance.cpp| 48 +++-
 utils/v4l2-compliance/v4l2-compliance.h  |  1 +
 utils/v4l2-compliance/v4l2-test-input-output.cpp |  4 +-
 3 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp 
b/utils/v4l2-compliance/v4l2-compliance.cpp
index 48dc8b4..6bd4653 100644
--- a/utils/v4l2-compliance/v4l2-compliance.cpp
+++ b/utils/v4l2-compliance/v4l2-compliance.cpp
@@ -55,6 +55,7 @@ enum Option {
OptSetRadioDevice = 'r',
OptStreaming = 's',
OptSetSWRadioDevice = 'S',
+   OptSetTouchDevice = 't',
OptTrace = 'T',
OptVerbose = 'v',
OptSetVbiDevice = 'V',
@@ -105,6 +106,7 @@ static struct option long_options[] = {
{"vbi-device", required_argument, 0, OptSetVbiDevice},
{"sdr-device", required_argument, 0, OptSetSWRadioDevice},
{"expbuf-device", required_argument, 0, OptSetExpBufDevice},
+   {"touch-device", required_argument, 0, OptSetTouchDevice},
{"help", no_argument, 0, OptHelp},
{"verbose", no_argument, 0, OptVerbose},
{"no-warnings", no_argument, 0, OptNoWarnings},
@@ -134,6 +136,9 @@ static void usage(void)
printf("  -S, --sdr-device=\n");
printf(" Use device  as the SDR device.\n");
printf(" If  starts with a digit, then 
/dev/swradio is used.\n");
+   printf("  -t, --touch-device=\n");
+   printf(" Use device  as the touch device.\n");
+   printf(" If  starts with a digit, then 
/dev/v4l-touch is used.\n");
printf("  -e, --expbuf-device=\n");
printf(" Use device  to obtain DMABUF 
handles.\n");
printf(" If  starts with a digit, then 
/dev/video is used.\n");
@@ -206,6 +211,8 @@ std::string cap2s(unsigned cap)
s += "\t\tSDR Capture\n";
if (cap & V4L2_CAP_SDR_OUTPUT)
s += "\t\tSDR Output\n";
+   if (cap & V4L2_CAP_TOUCH)
+   s += "\t\tTouch Capture\n";
if (cap & V4L2_CAP_TUNER)
s += "\t\tTuner\n";
if (cap & V4L2_CAP_HW_FREQ_SEEK)
@@ -673,6 +680,8 @@ int main(int argc, char **argv)
struct node radio_node2;
struct node sdr_node;
struct node sdr_node2;
+   struct node touch_node;
+   struct node touch_node2;
struct node expbuf_node;
 
/* command args */
@@ -682,6 +691,7 @@ int main(int argc, char **argv)
const char *vbi_device = NULL;  /* -V device */
const char *radio_device = NULL;/* -r device */
const char *sdr_device = NULL;  /* -S device */
+   const char *touch_device = NULL;/* -t device */
const char *expbuf_device = NULL;   /* --expbuf-device device */
struct v4l2_capability vcap;/* list_cap */
unsigned frame_count = 60;
@@ -750,6 +760,15 @@ int main(int argc, char **argv)
sdr_device = newdev;
}
break;
+   case OptSetTouchDevice:
+   touch_device = optarg;
+   if (touch_device[0] >= '0' && touch_device[0] <= '9' && 
strlen(touch_device) <= 3) {
+   static char newdev[20];
+
+   sprintf(newdev, "/dev/v4l-touch%s", 
touch_device);
+   touch_device = newdev;
+   }
+   break;
case OptSetExpBufDevice:
expbuf_device = optarg;
if (expbuf_device[0] >= '0' && expbuf_device[0] <= '9' 
&& strlen(expbuf_device) <= 3) {
@@ -839,7 +858,8 @@ int main(int argc, char **argv)
if (v1 == 2 && v2 == 6)
kernel_version = v3;
 
-   if (!video_device && !vbi_device && !radio_device && !sdr_device)
+   if (!video_device && !vbi_device && !radio_device &&
+   !sdr_device && !touch_device)
video_device = "/dev/video0";
 
if (video_device) {
@@ -886,6 +906,17 @@ int main(int argc, char **argv)
}
}
 
+   if (touch_device) {
+   touch_node.s_trace(options[OptTrace]);
+   touch_node.s_direct(direct);
+   fd = touch_node.open(touch_device, false);
+   if (fd < 0) {
+   fprintf(stderr, "Failed to open %s: %s\n", touch_de

Re: [PATCH v5 0/9] Output raw touch data via V4L2

2016-06-27 Thread Nick Dyer
On 27/06/2016 13:22, Hans Verkuil wrote:
> On 06/27/2016 01:57 PM, Nick Dyer wrote:
> 2) Alternatively, if we want to keep using BUF_TYPE_VIDEO_CAPTURE, then:
> 
> - we keep V4L2_CAP_TOUCH which is combined with CAP_VIDEO_CAPTURE (and perhaps
>   VIDEO_OUTPUT in the future). The CAP_TOUCH just says that this is a touch
>   device, not a video device, but otherwise it acts the same.
> 
> I'd go with 2, since I see no reason to add a new BUF_TYPE for this.
> It acts exactly like video after all, with only a few restrictions (i.e. no
> colorspace info or interlaced). And adding a new BUF_TYPE will likely break
> the existing sur40 app.

OK, I will rework with this approach.
--
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 v5 0/9] Output raw touch data via V4L2

2016-06-27 Thread Nick Dyer
Hi Hans-

Thanks for reviewing this again in such detail.

On 27/06/2016 12:26, Hans Verkuil wrote:
> On 06/23/2016 12:08 AM, Nick Dyer wrote:
>> This is a series of patches to add output of raw touch diagnostic data via 
>> V4L2
>> to the Atmel maXTouch and Synaptics RMI4 drivers.
>>
>> It's a rewrite of the previous implementation which output via debugfs: it 
>> now
>> uses a V4L2 device in a similar way to the sur40 driver.
>>
>> We have a utility which can read the data and display it in a useful format:
>> https://github.com/ndyer/heatmap/commits/heatmap-v4l
>>
>> These patches are also available from
>> https://github.com/ndyer/linux/commits/v4l-touch-2016-06-22
>>
>> Changes in v5 (Hans Verkuil review):
>> - Update v4l2-core:
>>   - Add VFL_TYPE_TOUCH, V4L2_BUF_TYPE_TOUCH_CAPTURE and V4L2_CAP_TOUCH
> 
> The use of V4L2_CAP_TOUCH and V4L2_BUF_TYPE_TOUCH_CAPTURE is very 
> inconsistent.
> What is the rationale of adding V4L2_BUF_TYPE_TOUCH_CAPTURE? I can't remember
> asking for it.

I am afraid that I missed updating atmel_mxt_ts from
V4L2_BUF_TYPE_VIDEO_CAPTURE to V4L2_BUF_TYPE_TOUCH_CAPTURE, which has
confused the situation.

Perhaps I read too much into your request that I look at the way that SDR
is treated. When I started going through the code paths in v4l2-core and
v4l2-compliance, it seemed cleaner to treat touch as completely separate,
hence introducing the new BUF_TYPE. I'm happy to try it without this.

> And wouldn't the use of V4L2_BUF_TYPE_TOUCH_CAPTURE break userspace for sur40?

I think it is likely, yes. And it looks like that would make Florian unhappy.

> I'm ambiguous towards having a V4L2_BUF_TYPE_TOUCH_CAPTURE, to be honest.
> 
> I would also recommend renaming V4L2_CAP_TOUCH to V4L2_CAP_TOUCH_CAPTURE.

Do you agree with the following changes:

- Rename V4L2_CAP_TOUCH to V4L2_CAP_TOUCH_CAPTURE.

- Touch devices should register both V4L2_CAP_VIDEO_CAPTURE and
V4L2_CAP_TOUCH_CAPTURE.

- Get rid of V4L2_BUF_TYPE_TOUCH_CAPTURE and use
V4L2_BUF_TYPE_VIDEO_CAPTURE. In v4l2-ioctl.c if we need to force particular
pix formats for touch, it will need to look at V4L2_CAP_TOUCH_CAPTURE.

Your other review comments look straightforward to address - thanks.

I should say, you can see my current changes to v4l2-compliance here:
https://github.com/ndyer/v4l-utils/commit/07e00c33

Should I post them along with the kernel patches next time?

> 
> I can imagine an embedded usb gadget device that outputs touch data to a PC.
> 
> 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: [PATCH] sur40: drop unnecessary format description

2016-06-27 Thread Nick Dyer
On 27/06/2016 11:25, Hans Verkuil wrote:
> Don't fill in the format description. This is now done in the V4L2 core to 
> ensure
> consistent descriptions.
> 
> Signed-off-by: Hans Verkuil <hans.verk...@cisco.com>

Acked-by: Nick Dyer <nick.d...@itdev.co.uk>

> 
> diff --git a/drivers/input/touchscreen/sur40.c 
> b/drivers/input/touchscreen/sur40.c
> index 880c40b..5f1617b 100644
> --- a/drivers/input/touchscreen/sur40.c
> +++ b/drivers/input/touchscreen/sur40.c
> @@ -793,7 +793,6 @@ static int sur40_vidioc_enum_fmt(struct file *file, void 
> *priv,
>  {
>   if (f->index != 0)
>   return -EINVAL;
> - strlcpy(f->description, "8-bit greyscale", sizeof(f->description));
>   f->pixelformat = V4L2_PIX_FMT_GREY;
>   f->flags = 0;
>   return 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


Re: [PATCH v5 1/9] [media] v4l2-core: Add support for touch devices

2016-06-24 Thread Nick Dyer


On 22/06/2016 23:08, Nick Dyer wrote:
> Some touch controllers send out touch data in a similar way to a
> greyscale frame grabber.
> 
> Use a new device prefix v4l-touch for these devices, to stop generic
> capture software from treating them as webcams.
> 
> Add formats:
> - V4L2_TCH_FMT_DELTA_TD16 for signed 16-bit touch deltas
> - V4L2_TCH_FMT_DELTA_TD08 for signed 16-bit touch deltas
> - V4L2_TCH_FMT_TU16 for unsigned 16-bit touch data
> - V4L2_TCH_FMT_TU08 for unsigned 8-bit touch data
> 
> This support will be used by:
> * Atmel maXTouch (atmel_mxt_ts)
> * Synaptics RMI4.
> * sur40
> 
> Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
> ---
[...]
> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> index 8f95191..7e19782 100644
> --- a/include/uapi/linux/videodev2.h
> +++ b/include/uapi/linux/videodev2.h
> @@ -143,6 +143,7 @@ enum v4l2_buf_type {
>   V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE  = 10,
>   V4L2_BUF_TYPE_SDR_CAPTURE  = 11,
>   V4L2_BUF_TYPE_SDR_OUTPUT   = 12,
> + V4L2_BUF_TYPE_TOUCH_CAPTURE= 13,
>   /* Deprecated, do not use */
>   V4L2_BUF_TYPE_PRIVATE  = 0x80,
>  };
> @@ -440,6 +441,8 @@ struct v4l2_capability {
>  #define V4L2_CAP_ASYNCIO0x0200  /* async I/O */
>  #define V4L2_CAP_STREAMING  0x0400  /* streaming I/O ioctls 
> */
>  
> +#define V4L2_CAP_TOUCH   0x0010  /* Is a touch 
> device */

Apologies, this should have been
#define V4L2_CAP_TOUCH 0x1000

You will find my changes to v4l2-compliance to support these changes here:
https://github.com/ndyer/v4l-utils

I've tested the atmel_mxt_ts version of this with v4l2-compliance on Pixel 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 v5 0/9] Output raw touch data via V4L2

2016-06-22 Thread Nick Dyer
This is a series of patches to add output of raw touch diagnostic data via V4L2
to the Atmel maXTouch and Synaptics RMI4 drivers.

It's a rewrite of the previous implementation which output via debugfs: it now
uses a V4L2 device in a similar way to the sur40 driver.

We have a utility which can read the data and display it in a useful format:
https://github.com/ndyer/heatmap/commits/heatmap-v4l

These patches are also available from
https://github.com/ndyer/linux/commits/v4l-touch-2016-06-22

Changes in v5 (Hans Verkuil review):
- Update v4l2-core:
  - Add VFL_TYPE_TOUCH, V4L2_BUF_TYPE_TOUCH_CAPTURE and V4L2_CAP_TOUCH
  - Change V4L2_INPUT_TYPE_TOUCH_SENSOR to V4L2_INPUT_TYPE_TOUCH
  - Improve DocBook documentation
  - Add FMT definitions for touch data
  - Note this will need the latest version of the heatmap util
- Synaptics RMI4 driver:
  - Remove some less important non full frame report types
  - Switch report type names to const char * array
  - Move a static array to inside context struct
- Split sur40 changes to a separate commit

Changes in v4:
- Address nits from the input side in atmel_mxt_ts patches (Dmitry Torokhov)
- Add Synaptics RMI4 F54 support patch

Changes in v3:
- Address V4L2 review comments from Hans Verkuil
- Run v4l-compliance and fix all issues - needs minor patch here:
  https://github.com/ndyer/v4l-utils/commit/cf50469773f

Changes in v2:
- Split pixfmt changes into separate commit and add DocBook
- Introduce VFL_TYPE_TOUCH_SENSOR and /dev/v4l-touch
- Remove "single node" support for now, it may be better to treat it as
  metadata later
- Explicitly set VFL_DIR_RX
- Fix Kconfig

--
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 v5 1/9] [media] v4l2-core: Add support for touch devices

2016-06-22 Thread Nick Dyer
Some touch controllers send out touch data in a similar way to a
greyscale frame grabber.

Use a new device prefix v4l-touch for these devices, to stop generic
capture software from treating them as webcams.

Add formats:
- V4L2_TCH_FMT_DELTA_TD16 for signed 16-bit touch deltas
- V4L2_TCH_FMT_DELTA_TD08 for signed 16-bit touch deltas
- V4L2_TCH_FMT_TU16 for unsigned 16-bit touch data
- V4L2_TCH_FMT_TU08 for unsigned 8-bit touch data

This support will be used by:
* Atmel maXTouch (atmel_mxt_ts)
* Synaptics RMI4.
* sur40

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 Documentation/DocBook/media/v4l/dev-touch.xml  | 53 ++
 Documentation/DocBook/media/v4l/media-types.xml|  5 ++
 .../DocBook/media/v4l/pixfmt-tch-td08.xml  | 66 +
 .../DocBook/media/v4l/pixfmt-tch-td16.xml  | 82 ++
 .../DocBook/media/v4l/pixfmt-tch-tu08.xml  | 66 +
 .../DocBook/media/v4l/pixfmt-tch-tu16.xml  | 81 +
 Documentation/DocBook/media/v4l/pixfmt.xml | 13 
 Documentation/DocBook/media/v4l/v4l2.xml   |  1 +
 drivers/media/v4l2-core/v4l2-dev.c | 16 -
 drivers/media/v4l2-core/v4l2-ioctl.c   | 44 
 drivers/media/v4l2-core/videobuf2-v4l2.c   |  1 +
 include/media/v4l2-dev.h   |  3 +-
 include/uapi/linux/media.h |  2 +
 include/uapi/linux/videodev2.h | 10 +++
 14 files changed, 439 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/dev-touch.xml
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-tch-td08.xml
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-tch-td16.xml
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-tch-tu08.xml
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-tch-tu16.xml

diff --git a/Documentation/DocBook/media/v4l/dev-touch.xml 
b/Documentation/DocBook/media/v4l/dev-touch.xml
new file mode 100644
index 000..9e36328
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/dev-touch.xml
@@ -0,0 +1,53 @@
+Touch Devices
+
+Touch devices are accessed through character device special files
+  named /dev/v4l-touch0 to
+  /dev/v4l-touch255 with major number 81 and
+  dynamically allocated minor numbers 0 to 255.
+
+
+  Overview
+
+  Sensors may be Optical, or Projected Capacitive touch (PCT).
+
+  Processing is required to analyse the raw data and produce input
+events. In some systems, this may be performed on the ASIC and the raw data
+is purely a side-channel for diagnostics or tuning. In other systems, the
+ASIC is a simple analogue front end device which delivers touch data at
+high rate, and any touch processing must be done on the host.
+
+  For capacitive touch sensing, the touchscreen is composed of an array
+of horizontal and vertical conductors (alternatively called rows/columns,
+X/Y lines, or tx/rx). Mutual Capacitance measured is at the nodes where the
+conductors cross. Alternatively, Self Capacitance measures the signal from
+each column and row independently.
+
+  A touch input may be determined by comparing the raw capacitance
+measurement to a no-touch reference (or "baseline") measurement:
+
+  Delta = Raw - Reference
+
+  The reference measurement takes account of variations in the
+capacitance across the touch sensor matrix, for example
+manufacturing irregularities, environmental or edge effects.
+
+
+
+  Querying Capabilities
+
+  Devices supporting the touch interface set the
+V4L2_CAP_VIDEO_CAPTURE flag in the
+capabilities field of 
+returned by the  ioctl.
+
+  At least one of the read/write, streaming or asynchronous I/O methods
+must be supported.
+
+
+
+  Data Format Negotiation
+
+   A touch device may support read/write
+and/or streaming (memory mapping or
+user pointer) I/O.
+
diff --git a/Documentation/DocBook/media/v4l/media-types.xml 
b/Documentation/DocBook/media/v4l/media-types.xml
index 5e3f20f..fb957c7 100644
--- a/Documentation/DocBook/media/v4l/media-types.xml
+++ b/Documentation/DocBook/media/v4l/media-types.xml
@@ -202,6 +202,11 @@
typically, /dev/swradio?
  
  
+   MEDIA_INTF_T_V4L_TOUCH
+   Device node interface for Touch device (V4L)
+   typically, /dev/v4l-touch?
+ 
+ 
MEDIA_INTF_T_ALSA_PCM_CAPTURE
Device node interface for ALSA PCM Capture
typically, /dev/snd/pcmC?D?c
diff --git a/Documentation/DocBook/media/v4l/pixfmt-tch-td08.xml 
b/Documentation/DocBook/media/v4l/pixfmt-tch-td08.xml
new file mode 100644
index 000..2483eb0
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/pixfmt-tch-td08.xml
@@ -0,0 +1,66 @@
+
+  
+V4L2_TCH_FMT_DELTA_TD08 ('TD08')
+
+  
+  
+V4L2_TCH_FMT_DELTA_TD08
+8-bit signed Touch Delta
+  
+  
+Description
+

[PATCH v5 6/9] Input: atmel_mxt_ts - add diagnostic data support for mXT1386

2016-06-22 Thread Nick Dyer
The mXT1386 family of chips have a different architecture which splits
the diagnostic data into 3 columns.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 31 ---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 3f7e357..739d138 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -137,6 +137,10 @@ struct t9_range {
 #define MXT_DIAGNOSTIC_DELTAS  0x10
 #define MXT_DIAGNOSTIC_SIZE128
 
+#define MXT_FAMILY_1386160
+#define MXT1386_COLUMNS3
+#define MXT1386_PAGES_PER_COLUMN   8
+
 struct t37_debug {
 #ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
u8 mode;
@@ -2140,13 +2144,27 @@ recheck:
 static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
   unsigned int y)
 {
+   struct mxt_info *info = >info;
struct mxt_dbg *dbg = >dbg;
unsigned int ofs, page;
+   unsigned int col = 0;
+   unsigned int col_width;
+
+   if (info->family_id == MXT_FAMILY_1386) {
+   col_width = info->matrix_ysize / MXT1386_COLUMNS;
+   col = y / col_width;
+   y = y % col_width;
+   } else {
+   col_width = info->matrix_ysize;
+   }
 
-   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   ofs = (y + (x * col_width)) * sizeof(u16);
page = ofs / MXT_DIAGNOSTIC_SIZE;
ofs %= MXT_DIAGNOSTIC_SIZE;
 
+   if (info->family_id == MXT_FAMILY_1386)
+   page += col * MXT1386_PAGES_PER_COLUMN;
+
return get_unaligned_le16(>t37_buf[page].data[ofs]);
 }
 
@@ -2416,6 +2434,7 @@ static const struct video_device mxt_video_device = {
 
 static void mxt_debug_init(struct mxt_data *data)
 {
+   struct mxt_info *info = >info;
struct mxt_dbg *dbg = >dbg;
struct mxt_object *object;
int error;
@@ -2439,8 +2458,14 @@ static void mxt_debug_init(struct mxt_data *data)
 
/* Calculate size of data and allocate buffer */
dbg->t37_nodes = data->xsize * data->ysize;
-   dbg->t37_pages = DIV_ROUND_UP(data->xsize * data->info.matrix_ysize *
- sizeof(u16), sizeof(dbg->t37_buf->data));
+
+   if (info->family_id == MXT_FAMILY_1386)
+   dbg->t37_pages = MXT1386_COLUMNS * MXT1386_PAGES_PER_COLUMN;
+   else
+   dbg->t37_pages = DIV_ROUND_UP(data->xsize *
+ data->info.matrix_ysize *
+ sizeof(u16),
+ sizeof(dbg->t37_buf->data));
 
dbg->t37_buf = devm_kmalloc_array(>client->dev, dbg->t37_pages,
  sizeof(struct t37_debug), GFP_KERNEL);
-- 
2.5.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


[PATCH v5 4/9] Input: atmel_mxt_ts - read touchscreen size

2016-06-22 Thread Nick Dyer
The touchscreen may have a margin where not all the matrix is used. Read
the parameters from T9 and T100 and take account of the difference.

Note: this does not read the XORIGIN/YORIGIN fields so it assumes that
the touchscreen starts at (0,0)

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 42 +++-
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 7780d38..8ef61d7 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -103,6 +103,8 @@ struct t7_config {
 
 /* MXT_TOUCH_MULTI_T9 field */
 #define MXT_T9_CTRL0
+#define MXT_T9_XSIZE   3
+#define MXT_T9_YSIZE   4
 #define MXT_T9_ORIENT  9
 #define MXT_T9_RANGE   18
 
@@ -150,7 +152,9 @@ struct t37_debug {
 #define MXT_T100_CTRL  0
 #define MXT_T100_CFG1  1
 #define MXT_T100_TCHAUX3
+#define MXT_T100_XSIZE 9
 #define MXT_T100_XRANGE13
+#define MXT_T100_YSIZE 20
 #define MXT_T100_YRANGE24
 
 #define MXT_T100_CFG_SWITCHXY  BIT(5)
@@ -259,6 +263,8 @@ struct mxt_data {
unsigned int max_x;
unsigned int max_y;
bool xy_switch;
+   u8 xsize;
+   u8 ysize;
bool in_bootloader;
u16 mem_size;
u8 t100_aux_ampl;
@@ -1714,6 +1720,18 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return -EINVAL;
 
error = __mxt_read_reg(client,
+  object->start_address + MXT_T9_XSIZE,
+  sizeof(data->xsize), >xsize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T9_YSIZE,
+  sizeof(data->ysize), >ysize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
   object->start_address + MXT_T9_RANGE,
   sizeof(range), );
if (error)
@@ -1763,6 +1781,18 @@ static int mxt_read_t100_config(struct mxt_data *data)
 
data->max_y = get_unaligned_le16(_y);
 
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T100_XSIZE,
+  sizeof(data->xsize), >xsize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T100_YSIZE,
+  sizeof(data->ysize), >ysize);
+   if (error)
+   return error;
+
/* read orientation config */
error =  __mxt_read_reg(client,
object->start_address + MXT_T100_CFG1,
@@ -2121,7 +2151,7 @@ static int mxt_convert_debug_pages(struct mxt_data *data, 
u16 *outbuf)
outbuf[i] = mxt_get_debug_value(data, x, y);
 
/* Next value */
-   if (++x >= data->info.matrix_xsize) {
+   if (++x >= data->xsize) {
x = 0;
y++;
}
@@ -2276,8 +2306,8 @@ static int mxt_set_input(struct mxt_data *data, unsigned 
int i)
if (i > 0)
return -EINVAL;
 
-   f->width = data->info.matrix_xsize;
-   f->height = data->info.matrix_ysize;
+   f->width = data->xsize;
+   f->height = data->ysize;
f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
@@ -2392,9 +2422,9 @@ static void mxt_debug_init(struct mxt_data *data)
dbg->t37_address = object->start_address;
 
/* Calculate size of data and allocate buffer */
-   dbg->t37_nodes = data->info.matrix_xsize * data->info.matrix_ysize;
-   dbg->t37_pages = DIV_ROUND_UP(dbg->t37_nodes * sizeof(u16),
- sizeof(dbg->t37_buf->data));
+   dbg->t37_nodes = data->xsize * data->ysize;
+   dbg->t37_pages = DIV_ROUND_UP(data->xsize * data->info.matrix_ysize *
+ sizeof(u16), sizeof(dbg->t37_buf->data));
 
dbg->t37_buf = devm_kmalloc_array(>client->dev, dbg->t37_pages,
  sizeof(struct t37_debug), GFP_KERNEL);
-- 
2.5.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


[PATCH v5 2/9] Input: atmel_mxt_ts - add support for T37 diagnostic data

2016-06-22 Thread Nick Dyer
Atmel maXTouch devices have a T37 object which can be used to read raw
touch deltas from the device. This consists of an array of 16-bit
integers, one for each node on the touchscreen matrix.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/Kconfig|   6 ++
 drivers/input/touchscreen/atmel_mxt_ts.c | 159 +++
 2 files changed, 165 insertions(+)

diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index 8ecdc38..da96ecf 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -115,6 +115,12 @@ config TOUCHSCREEN_ATMEL_MXT
  To compile this driver as a module, choose M here: the
  module will be called atmel_mxt_ts.
 
+config TOUCHSCREEN_ATMEL_MXT_T37
+   bool "Support T37 Diagnostic Data"
+   depends on TOUCHSCREEN_ATMEL_MXT
+   help
+ Say Y here if you want support for the T37 Diagnostic Data object.
+
 config TOUCHSCREEN_AUO_PIXCIR
tristate "AUO in-cell touchscreen using Pixcir ICs"
depends on I2C
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 5af7907..0048233 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -124,6 +124,19 @@ struct t9_range {
 #define MXT_COMMS_CTRL 0
 #define MXT_COMMS_CMD  1
 
+/* MXT_DEBUG_DIAGNOSTIC_T37 */
+#define MXT_DIAGNOSTIC_PAGEUP  0x01
+#define MXT_DIAGNOSTIC_DELTAS  0x10
+#define MXT_DIAGNOSTIC_SIZE128
+
+struct t37_debug {
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+   u8 mode;
+   u8 page;
+   u8 data[MXT_DIAGNOSTIC_SIZE];
+#endif
+};
+
 /* Define for MXT_GEN_COMMAND_T6 */
 #define MXT_BOOT_VALUE 0xa5
 #define MXT_RESET_VALUE0x01
@@ -205,6 +218,14 @@ struct mxt_object {
u8 num_report_ids;
 } __packed;
 
+struct mxt_dbg {
+   u16 t37_address;
+   u16 diag_cmd_address;
+   struct t37_debug *t37_buf;
+   unsigned int t37_pages;
+   unsigned int t37_nodes;
+};
+
 /* Each client has this additional data */
 struct mxt_data {
struct i2c_client *client;
@@ -233,6 +254,7 @@ struct mxt_data {
u8 num_touchids;
u8 multitouch;
struct t7_config t7_cfg;
+   struct mxt_dbg dbg;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -2043,6 +2065,141 @@ recheck:
return 0;
 }
 
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
+  unsigned int y)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int ofs, page;
+
+   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   page = ofs / MXT_DIAGNOSTIC_SIZE;
+   ofs %= MXT_DIAGNOSTIC_SIZE;
+
+   return get_unaligned_le16(>t37_buf[page].data[ofs]);
+}
+
+static int mxt_convert_debug_pages(struct mxt_data *data, u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int x = 0;
+   unsigned int y = 0;
+   unsigned int i;
+
+   for (i = 0; i < dbg->t37_nodes; i++) {
+   outbuf[i] = mxt_get_debug_value(data, x, y);
+
+   /* Next value */
+   if (++x >= data->info.matrix_xsize) {
+   x = 0;
+   y++;
+   }
+   }
+
+   return 0;
+}
+
+static int mxt_read_diagnostic_debug(struct mxt_data *data, u8 mode,
+u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   int retries = 0;
+   int page;
+   int ret;
+   u8 cmd = mode;
+   struct t37_debug *p;
+   u8 cmd_poll;
+
+   for (page = 0; page < dbg->t37_pages; page++) {
+   p = dbg->t37_buf + page;
+
+   ret = mxt_write_reg(data->client, dbg->diag_cmd_address,
+   cmd);
+   if (ret)
+   return ret;
+
+   retries = 0;
+   msleep(20);
+wait_cmd:
+   /* Read back command byte */
+   ret = __mxt_read_reg(data->client, dbg->diag_cmd_address,
+sizeof(cmd_poll), _poll);
+   if (ret)
+   return ret;
+
+   /* Field is cleared once the command has been processed */
+   if (cmd_poll) {
+   if (retries++ > 100)
+   return -EINVAL;
+
+   msleep(20);
+   goto wait_cmd;
+   }
+
+   /* Read T37 page */
+   ret = __mxt_read_reg(data->client, dbg->t37_address,
+sizeof(struct t37_debug), p);
+   if (ret)
+   return ret;
+
+   if (p->mode != mode || p->page != page) {
+  

[PATCH v5 5/9] Input: atmel_mxt_ts - handle diagnostic data orientation

2016-06-22 Thread Nick Dyer
Invert the diagnostic data to match the orientation of the input device.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 26 +-
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 8ef61d7..3f7e357 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -125,6 +125,8 @@ struct t9_range {
 
 /* MXT_TOUCH_MULTI_T9 orient */
 #define MXT_T9_ORIENT_SWITCH   (1 << 0)
+#define MXT_T9_ORIENT_INVERTX  (1 << 1)
+#define MXT_T9_ORIENT_INVERTY  (1 << 2)
 
 /* MXT_SPT_COMMSCONFIG_T18 */
 #define MXT_COMMS_CTRL 0
@@ -158,6 +160,8 @@ struct t37_debug {
 #define MXT_T100_YRANGE24
 
 #define MXT_T100_CFG_SWITCHXY  BIT(5)
+#define MXT_T100_CFG_INVERTY   BIT(6)
+#define MXT_T100_CFG_INVERTX   BIT(7)
 
 #define MXT_T100_TCHAUX_VECT   BIT(0)
 #define MXT_T100_TCHAUX_AMPL   BIT(1)
@@ -262,6 +266,8 @@ struct mxt_data {
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
+   bool invertx;
+   bool inverty;
bool xy_switch;
u8 xsize;
u8 ysize;
@@ -1747,6 +1753,8 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return error;
 
data->xy_switch = orient & MXT_T9_ORIENT_SWITCH;
+   data->invertx = orient & MXT_T9_ORIENT_INVERTX;
+   data->inverty = orient & MXT_T9_ORIENT_INVERTY;
 
return 0;
 }
@@ -1801,6 +1809,8 @@ static int mxt_read_t100_config(struct mxt_data *data)
return error;
 
data->xy_switch = cfg & MXT_T100_CFG_SWITCHXY;
+   data->invertx = cfg & MXT_T100_CFG_INVERTX;
+   data->inverty = cfg & MXT_T100_CFG_INVERTY;
 
/* allocate aux bytes */
error =  __mxt_read_reg(client,
@@ -2145,13 +2155,19 @@ static int mxt_convert_debug_pages(struct mxt_data 
*data, u16 *outbuf)
struct mxt_dbg *dbg = >dbg;
unsigned int x = 0;
unsigned int y = 0;
-   unsigned int i;
+   unsigned int i, rx, ry;
 
for (i = 0; i < dbg->t37_nodes; i++) {
-   outbuf[i] = mxt_get_debug_value(data, x, y);
+   /* Handle orientation */
+   rx = data->xy_switch ? y : x;
+   ry = data->xy_switch ? x : y;
+   rx = data->invertx ? (data->xsize - 1 - rx) : rx;
+   ry = data->inverty ? (data->ysize - 1 - ry) : ry;
+
+   outbuf[i] = mxt_get_debug_value(data, rx, ry);
 
/* Next value */
-   if (++x >= data->xsize) {
+   if (++x >= (data->xy_switch ? data->ysize : data->xsize)) {
x = 0;
y++;
}
@@ -2306,8 +2322,8 @@ static int mxt_set_input(struct mxt_data *data, unsigned 
int i)
if (i > 0)
return -EINVAL;
 
-   f->width = data->xsize;
-   f->height = data->ysize;
+   f->width = data->xy_switch ? data->ysize : data->xsize;
+   f->height = data->xy_switch ? data->xsize : data->ysize;
f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
-- 
2.5.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


[PATCH v5 7/9] Input: atmel_mxt_ts - add support for reference data

2016-06-22 Thread Nick Dyer
There are different datatypes available from a maXTouch chip. Add
support to retrieve reference data as well.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 58 
 1 file changed, 51 insertions(+), 7 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 739d138..f733785 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -135,6 +135,7 @@ struct t9_range {
 /* MXT_DEBUG_DIAGNOSTIC_T37 */
 #define MXT_DIAGNOSTIC_PAGEUP  0x01
 #define MXT_DIAGNOSTIC_DELTAS  0x10
+#define MXT_DIAGNOSTIC_REFS0x11
 #define MXT_DIAGNOSTIC_SIZE128
 
 #define MXT_FAMILY_1386160
@@ -249,6 +250,12 @@ struct mxt_dbg {
int input;
 };
 
+enum v4l_dbg_inputs {
+   MXT_V4L_INPUT_DELTAS,
+   MXT_V4L_INPUT_REFS,
+   MXT_V4L_INPUT_MAX,
+};
+
 static const struct v4l2_file_operations mxt_video_fops = {
.owner = THIS_MODULE,
.open = v4l2_fh_open,
@@ -2273,6 +2280,7 @@ static void mxt_buffer_queue(struct vb2_buffer *vb)
struct mxt_data *data = vb2_get_drv_priv(vb->vb2_queue);
u16 *ptr;
int ret;
+   u8 mode;
 
ptr = vb2_plane_vaddr(vb, 0);
if (!ptr) {
@@ -2280,7 +2288,18 @@ static void mxt_buffer_queue(struct vb2_buffer *vb)
goto fault;
}
 
-   ret = mxt_read_diagnostic_debug(data, MXT_DIAGNOSTIC_DELTAS, ptr);
+   switch (data->dbg.input) {
+   case MXT_V4L_INPUT_DELTAS:
+   default:
+   mode = MXT_DIAGNOSTIC_DELTAS;
+   break;
+
+   case MXT_V4L_INPUT_REFS:
+   mode = MXT_DIAGNOSTIC_REFS;
+   break;
+   }
+
+   ret = mxt_read_diagnostic_debug(data, mode, ptr);
if (ret)
goto fault;
 
@@ -2325,11 +2344,20 @@ static int mxt_vidioc_querycap(struct file *file, void 
*priv,
 static int mxt_vidioc_enum_input(struct file *file, void *priv,
   struct v4l2_input *i)
 {
-   if (i->index > 0)
+   if (i->index >= MXT_V4L_INPUT_MAX)
return -EINVAL;
 
i->type = V4L2_INPUT_TYPE_TOUCH;
-   strlcpy(i->name, "Mutual References", sizeof(i->name));
+
+   switch (i->index) {
+   case MXT_V4L_INPUT_REFS:
+   strlcpy(i->name, "Mutual References", sizeof(i->name));
+   break;
+   case MXT_V4L_INPUT_DELTAS:
+   strlcpy(i->name, "Mutual Deltas", sizeof(i->name));
+   break;
+   }
+
return 0;
 }
 
@@ -2337,12 +2365,16 @@ static int mxt_set_input(struct mxt_data *data, 
unsigned int i)
 {
struct v4l2_pix_format *f = >dbg.format;
 
-   if (i > 0)
+   if (i >= MXT_V4L_INPUT_MAX)
return -EINVAL;
 
+   if (i == MXT_V4L_INPUT_DELTAS)
+   f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
+   else
+   f->pixelformat = V4L2_TCH_FMT_TU16;
+
f->width = data->xy_switch ? data->ysize : data->xsize;
f->height = data->xy_switch ? data->xsize : data->ysize;
-   f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
f->bytesperline = f->width * sizeof(u16);
@@ -2380,10 +2412,22 @@ static int mxt_vidioc_fmt(struct file *file, void 
*priv, struct v4l2_format *f)
 static int mxt_vidioc_enum_fmt(struct file *file, void *priv,
 struct v4l2_fmtdesc *fmt)
 {
-   if (fmt->index > 0 || fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   return -EINVAL;
+
+   switch (fmt->index) {
+   case 0:
+   fmt->pixelformat = V4L2_TCH_FMT_TU16;
+   break;
+
+   case 1:
+   fmt->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
+   break;
+
+   default:
return -EINVAL;
+   }
 
-   fmt->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
return 0;
 }
 
-- 
2.5.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


[PATCH v5 9/9] Input: sur40 - use new V4L2 touch input type

2016-06-22 Thread Nick Dyer
Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/sur40.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/sur40.c 
b/drivers/input/touchscreen/sur40.c
index 880c40b..841e045 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -599,7 +599,7 @@ static int sur40_probe(struct usb_interface *interface,
sur40->vdev.queue = >queue;
video_set_drvdata(>vdev, sur40);
 
-   error = video_register_device(>vdev, VFL_TYPE_GRABBER, -1);
+   error = video_register_device(>vdev, VFL_TYPE_TOUCH, -1);
if (error) {
dev_err(>dev,
"Unable to register video subdevice.");
@@ -763,7 +763,7 @@ static int sur40_vidioc_enum_input(struct file *file, void 
*priv,
 {
if (i->index != 0)
return -EINVAL;
-   i->type = V4L2_INPUT_TYPE_CAMERA;
+   i->type = V4L2_INPUT_TYPE_TOUCH;
i->std = V4L2_STD_UNKNOWN;
strlcpy(i->name, "In-Cell Sensor", sizeof(i->name));
i->capabilities = 0;
@@ -794,7 +794,7 @@ static int sur40_vidioc_enum_fmt(struct file *file, void 
*priv,
if (f->index != 0)
return -EINVAL;
strlcpy(f->description, "8-bit greyscale", sizeof(f->description));
-   f->pixelformat = V4L2_PIX_FMT_GREY;
+   f->pixelformat = V4L2_TCH_FMT_TU08;
f->flags = 0;
return 0;
 }
@@ -802,7 +802,7 @@ static int sur40_vidioc_enum_fmt(struct file *file, void 
*priv,
 static int sur40_vidioc_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *f)
 {
-   if ((f->index != 0) || (f->pixel_format != V4L2_PIX_FMT_GREY))
+   if ((f->index != 0) || (f->pixel_format != V4L2_TCH_FMT_TU08))
return -EINVAL;
 
f->type = V4L2_FRMSIZE_TYPE_DISCRETE;
@@ -814,7 +814,7 @@ static int sur40_vidioc_enum_framesizes(struct file *file, 
void *priv,
 static int sur40_vidioc_enum_frameintervals(struct file *file, void *priv,
struct v4l2_frmivalenum *f)
 {
-   if ((f->index > 1) || (f->pixel_format != V4L2_PIX_FMT_GREY)
+   if ((f->index > 1) || (f->pixel_format != V4L2_TCH_FMT_TU08)
|| (f->width  != sur40_video_format.width)
|| (f->height != sur40_video_format.height))
return -EINVAL;
@@ -903,7 +903,7 @@ static const struct video_device sur40_video_device = {
 };
 
 static const struct v4l2_pix_format sur40_video_format = {
-   .pixelformat = V4L2_PIX_FMT_GREY,
+   .pixelformat = V4L2_TCH_FMT_TU08,
.width  = SENSOR_RES_X / 2,
.height = SENSOR_RES_Y / 2,
.field = V4L2_FIELD_NONE,
-- 
2.5.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


[PATCH v5 8/9] Input: synaptics-rmi4 - add support for F54 diagnostics

2016-06-22 Thread Nick Dyer
Function 54 implements access to various RMI4 diagnostic features.

This patch adds support for retrieving this data. It registers a V4L2
device to output the data to user space.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/rmi4/Kconfig  |  11 +
 drivers/input/rmi4/Makefile |   1 +
 drivers/input/rmi4/rmi_bus.c|   3 +
 drivers/input/rmi4/rmi_driver.h |   1 +
 drivers/input/rmi4/rmi_f54.c| 730 
 5 files changed, 746 insertions(+)
 create mode 100644 drivers/input/rmi4/rmi_f54.c

diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
index f73df24..f3418b6 100644
--- a/drivers/input/rmi4/Kconfig
+++ b/drivers/input/rmi4/Kconfig
@@ -61,3 +61,14 @@ config RMI4_F30
 
  Function 30 provides GPIO and LED support for RMI4 devices. This
  includes support for buttons on TouchPads and ClickPads.
+
+config RMI4_F54
+   bool "RMI4 Function 54 (Analog diagnostics)"
+   depends on RMI4_CORE
+   depends on VIDEO_V4L2
+   select VIDEOBUF2_VMALLOC
+   help
+ Say Y here if you want to add support for RMI4 function 54
+
+ Function 54 provides access to various diagnostic features in certain
+ RMI4 touch sensors.
diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index 95c00a7..0bafc85 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -7,6 +7,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
+rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 
 # Transports
 obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o
diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index b368b05..3aedc65 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -315,6 +315,9 @@ static struct rmi_function_handler *fn_handlers[] = {
 #ifdef CONFIG_RMI4_F30
_f30_handler,
 #endif
+#ifdef CONFIG_RMI4_F54
+   _f54_handler,
+#endif
 };
 
 static void __rmi_unregister_function_handlers(int start_idx)
diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
index 6e140fa..8dfbebe 100644
--- a/drivers/input/rmi4/rmi_driver.h
+++ b/drivers/input/rmi4/rmi_driver.h
@@ -102,4 +102,5 @@ extern struct rmi_function_handler rmi_f01_handler;
 extern struct rmi_function_handler rmi_f11_handler;
 extern struct rmi_function_handler rmi_f12_handler;
 extern struct rmi_function_handler rmi_f30_handler;
+extern struct rmi_function_handler rmi_f54_handler;
 #endif
diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c
new file mode 100644
index 000..df4c821
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f54.c
@@ -0,0 +1,730 @@
+/*
+ * Copyright (c) 2012-2015 Synaptics Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "rmi_driver.h"
+
+#define F54_NAME   "rmi4_f54"
+
+/* F54 data offsets */
+#define F54_REPORT_DATA_OFFSET  3
+#define F54_FIFO_OFFSET 1
+#define F54_NUM_TX_OFFSET   1
+#define F54_NUM_RX_OFFSET   0
+
+/* F54 commands */
+#define F54_GET_REPORT  1
+#define F54_FORCE_CAL   2
+
+/* Fixed sizes of reports */
+#define F54_QUERY_LEN  27
+
+/* F54 capabilities */
+#define F54_CAP_BASELINE   (1 << 2)
+#define F54_CAP_IMAGE8 (1 << 3)
+#define F54_CAP_IMAGE16(1 << 6)
+
+enum rmi_f54_report_type {
+   F54_REPORT_NONE = 0,
+   F54_8BIT_IMAGE = 1,
+   F54_16BIT_IMAGE = 2,
+   F54_RAW_16BIT_IMAGE = 3,
+   F54_TRUE_BASELINE = 9,
+   F54_FULL_RAW_CAP = 19,
+   F54_FULL_RAW_CAP_RX_COUPLING_COMP = 20,
+   F54_MAX_REPORT_TYPE,
+};
+
+const char *rmi_f54_report_type_names[] = {
+   [F54_REPORT_NONE]   = "No report",
+   [F54_8BIT_IMAGE]= "8 bit image",
+   [F54_16BIT_IMAGE]   = "16 bit image",
+   [F54_RAW_16BIT_IMAGE]   = "Raw 16 bit image",
+   [F54_TRUE_BASELINE] = "True baseline",
+   [F54_FULL_RAW_CAP]  = "Full raw cap",
+   [F54_FULL_RAW_CAP_RX_COUPLING_COMP]
+   = "Full raw cap RX coupling comp",
+   [F54_MAX_REPORT_TYPE]   = "Max report type",
+};
+
+#define f54_reptype_name(a) (((unsigned)(a)) < 
ARRAY_SIZE(rmi_f54_report_type_names) ? rmi_f54_report_type_names[a] : 
"unknown")
+
+struct rmi_f54_reports {
+   int start;
+   int size;
+};
+
+struct f54_data {
+   struct 

[PATCH v5 3/9] Input: atmel_mxt_ts - output diagnostic debug via v4l2 device

2016-06-22 Thread Nick Dyer
Register a video device to output T37 diagnostic data.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/Kconfig|   6 +-
 drivers/input/touchscreen/atmel_mxt_ts.c | 244 +++
 2 files changed, 248 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index da96ecf..7c1c5ec 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -117,9 +117,11 @@ config TOUCHSCREEN_ATMEL_MXT
 
 config TOUCHSCREEN_ATMEL_MXT_T37
bool "Support T37 Diagnostic Data"
-   depends on TOUCHSCREEN_ATMEL_MXT
+   depends on TOUCHSCREEN_ATMEL_MXT && VIDEO_V4L2
+   select VIDEOBUF2_VMALLOC
help
- Say Y here if you want support for the T37 Diagnostic Data object.
+ Say Y here if you want support to output data from the T37
+ Diagnostic Data object using a V4L device.
 
 config TOUCHSCREEN_AUO_PIXCIR
tristate "AUO in-cell touchscreen using Pixcir ICs"
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 0048233..7780d38 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -28,6 +28,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 /* Firmware files */
 #define MXT_FW_NAME"maxtouch.fw"
@@ -224,6 +228,23 @@ struct mxt_dbg {
struct t37_debug *t37_buf;
unsigned int t37_pages;
unsigned int t37_nodes;
+
+   struct v4l2_device v4l2;
+   struct v4l2_pix_format format;
+   struct video_device vdev;
+   struct vb2_queue queue;
+   struct mutex lock;
+   int input;
+};
+
+static const struct v4l2_file_operations mxt_video_fops = {
+   .owner = THIS_MODULE,
+   .open = v4l2_fh_open,
+   .release = vb2_fop_release,
+   .unlocked_ioctl = video_ioctl2,
+   .read = vb2_fop_read,
+   .mmap = vb2_fop_mmap,
+   .poll = vb2_fop_poll,
 };
 
 /* Each client has this additional data */
@@ -279,6 +300,11 @@ struct mxt_data {
struct completion crc_completion;
 };
 
+struct mxt_vb2_buffer {
+   struct vb2_buffer   vb;
+   struct list_headlist;
+};
+
 static size_t mxt_obj_size(const struct mxt_object *obj)
 {
return obj->size_minus_one + 1;
@@ -1525,6 +1551,11 @@ static void mxt_free_input_device(struct mxt_data *data)
 
 static void mxt_free_object_table(struct mxt_data *data)
 {
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+   video_unregister_device(>dbg.vdev);
+   v4l2_device_unregister(>dbg.v4l2);
+#endif
+
kfree(data->object_table);
data->object_table = NULL;
kfree(data->msg_buf);
@@ -2157,10 +2188,191 @@ wait_cmd:
return mxt_convert_debug_pages(data, outbuf);
 }
 
+static int mxt_queue_setup(struct vb2_queue *q,
+  unsigned int *nbuffers, unsigned int *nplanes,
+  unsigned int sizes[], void *alloc_ctxs[])
+{
+   struct mxt_data *data = q->drv_priv;
+   size_t size = data->dbg.t37_nodes * sizeof(u16);
+
+   if (*nplanes)
+   return sizes[0] < size ? -EINVAL : 0;
+
+   *nplanes = 1;
+   sizes[0] = size;
+
+   return 0;
+}
+
+static void mxt_buffer_queue(struct vb2_buffer *vb)
+{
+   struct mxt_data *data = vb2_get_drv_priv(vb->vb2_queue);
+   u16 *ptr;
+   int ret;
+
+   ptr = vb2_plane_vaddr(vb, 0);
+   if (!ptr) {
+   dev_err(>client->dev, "Error acquiring frame ptr\n");
+   goto fault;
+   }
+
+   ret = mxt_read_diagnostic_debug(data, MXT_DIAGNOSTIC_DELTAS, ptr);
+   if (ret)
+   goto fault;
+
+   vb2_set_plane_payload(vb, 0, data->dbg.t37_nodes * sizeof(u16));
+   vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+   return;
+
+fault:
+   vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+}
+
+/* V4L2 structures */
+static const struct vb2_ops mxt_queue_ops = {
+   .queue_setup= mxt_queue_setup,
+   .buf_queue  = mxt_buffer_queue,
+   .wait_prepare   = vb2_ops_wait_prepare,
+   .wait_finish= vb2_ops_wait_finish,
+};
+
+static const struct vb2_queue mxt_queue = {
+   .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+   .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ,
+   .buf_struct_size = sizeof(struct mxt_vb2_buffer),
+   .ops = _queue_ops,
+   .mem_ops = _vmalloc_memops,
+   .timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC,
+   .min_buffers_needed = 1,
+};
+
+static int mxt_vidioc_querycap(struct file *file, void *priv,
+struct v4l2_capability *cap)
+{
+   struct mxt_data *data = video_drvdata(file);
+
+   strlcpy(cap->driver, "atmel_mxt_ts", sizeof(cap->driver));
+ 

Re: [PATCH v4 2/9] [media] v4l2-core: Add VFL_TYPE_TOUCH_SENSOR

2016-06-22 Thread Nick Dyer
On 22/06/2016 21:38, Florian Echtler wrote:
> On Wed, 22 Jun 2016, Nick Dyer wrote:
> 
>> On 22/06/2016 12:48, Florian Echtler wrote:
>>> On 20.06.2016 14:00, Hans Verkuil wrote:
>>>> On 06/17/2016 04:16 PM, Nick Dyer wrote:
>>>>>
>>>>> Use a new device prefix v4l-touch for these devices, to stop generic
>>>>> capture software from treating them as webcams.
>>
>>> Come to think of it, wouldn't it make sense to expose the other touch
>>> devices as generic frame grabbers, too, so you can easily view the debug
>>> output with any generic tool like cheese?
>>
>> While I like the idea of being able to use the generic tools, I think we
>> needed to do something to stop these devices turning up in e.g. video
>> conferencing software - it would cause a lot of confusion. There's nothing
>> stopping particular tools adding the necessary code to handle touch devices
>> if they feel their users want it.
> 
> Just to clarify: from the userspace point-of-view, would this change simply
> modify the prefix of the device node (i.e. /dev/video1 -> /dev/v4l-touch1),
> or would it somehow affect the API? If it's just the device node name, then
> that shouldn't be a problem after all, because e.g. reacTIVision requires
> you to specify the exact camera to be used anyway.

With the changes that Hans Verkuil has asked me to do:
* The device node is /dev/v4l-touch0-255
* There are several new formats eg. V4L2_TCH_FMT_DELTA_TD16 (16 bit deltas)
* I've defined new types VFL_TYPE_TOUCH, V4L2_BUF_TYPE_TOUCH_CAPTURE,
V4L2_INPUT_TYPE_TOUCH

We're just testing the changes, I hope to post an updated version soon.
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 2/9] [media] v4l2-core: Add VFL_TYPE_TOUCH_SENSOR

2016-06-22 Thread Nick Dyer
On 22/06/2016 12:48, Florian Echtler wrote:
> On 20.06.2016 14:00, Hans Verkuil wrote:
>> On 06/17/2016 04:16 PM, Nick Dyer wrote:
>>> Some touch controllers send out raw touch data in a similar way to a
>>> greyscale frame grabber. Add a new device type for these devices.
>>>
>>> Use a new device prefix v4l-touch for these devices, to stop generic
>>> capture software from treating them as webcams.
>>>
>>> Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
>>> ---
>>>  drivers/input/touchscreen/sur40.c|  4 ++--
>>>  drivers/media/v4l2-core/v4l2-dev.c   | 13 ++---
>>>  drivers/media/v4l2-core/v4l2-ioctl.c | 15 ++-
>>>  include/media/v4l2-dev.h |  3 ++-
>>>  include/uapi/linux/videodev2.h   |  1 +
> 
> Generally a good idea in my opinion, but I think the SUR40 is a special
> case: the whole point of putting in a V4L2 driver was that software like
> reacTIVision, which already has a V4L2 interface, can then use that
> device like any other camera.

Thanks. I see that reactivision definitely uses this already
(https://github.com/mkalten/reacTIVision/issues/3 ) and we don't want to
break it - I've split the sur40.c change out of this patch now so it can be
considered separately.

> Come to think of it, wouldn't it make sense to expose the other touch
> devices as generic frame grabbers, too, so you can easily view the debug
> output with any generic tool like cheese?

While I like the idea of being able to use the generic tools, I think we
needed to do something to stop these devices turning up in e.g. video
conferencing software - it would cause a lot of confusion. There's nothing
stopping particular tools adding the necessary code to handle touch devices
if they feel their users want it.

Also, the RMI4 and Atmel mXT touchscreens output signed data, which
unfortunately would confuse the generic tools.
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 9/9] Input: synaptics-rmi4 - add support for F54 diagnostics

2016-06-21 Thread Nick Dyer
On 20/06/2016 17:20, Hans Verkuil wrote:
> On 06/17/2016 04:16 PM, Nick Dyer wrote:
>> +static int rmi_f54_vidioc_enum_input(struct file *file, void *priv,
>> + struct v4l2_input *i)
>> +{
>> +struct f54_data *f54 = video_drvdata(file);
>> +enum f54_report_type reptype;
>> +
>> +reptype = rmi_f54_get_reptype(f54, i->index);
>> +if (reptype == F54_REPORT_NONE)
>> +return -EINVAL;
>> +
>> +i->type = V4L2_INPUT_TYPE_TOUCH_SENSOR;
>> +strlcpy(i->name, rmi_f54_reptype_str(reptype), sizeof(i->name));
> 
> Hmm, this doesn't feel right, but I don't have enough knowledge to decide if
> using inputs for this is the right approach.
> 
> One thing that strikes me as odd is that both F54_8BIT_IMAGE and 
> F54_16BIT_IMAGE
> both seem to return signed 16 bit samples. I would expect this to result in
> different pixel formats.

Yes, you're right. I've had a look at this area now and fixed it up. I've
added pixel formats for the various types of touch data so we will never
emit anything that's not under V4L2_TCH_FMT.

I've also worked on adding the DocBook documentation that was missing,
cribbing from SDR as you suggested. I think I've found all the places it
was needed now.

> I have no idea what all these inputs mean. Are they all actually needed?
> Would this perhaps be better implemented through a menu control?

These are the various types of tuning or fault finding data that users
expect to be able to access via the RMI4 F54 diagnostics function. Although
I would have to do some digging to give an detailed use case for each one.
Due to the way that F54 is implemented, only one data source can be
selected at once. So it seemed fairly reasonable to me to map it to inputs.

> I generally go by the philosophy that if I can't understand it, then it is
> likely that others won't either :-)

No problem.
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 8/9] Input: atmel_mxt_ts - add support for reference data

2016-06-20 Thread Nick Dyer
On 20/06/2016 17:09, Hans Verkuil wrote:
> On 06/17/2016 04:16 PM, Nick Dyer wrote:
>> @@ -2325,11 +2344,20 @@ static int mxt_vidioc_querycap(struct file *file, 
>> void *priv,
>>  static int mxt_vidioc_enum_input(struct file *file, void *priv,
>> struct v4l2_input *i)
>>  {
>> -if (i->index > 0)
>> +if (i->index >= MXT_V4L_INPUT_MAX)
>>  return -EINVAL;
>>  
>>  i->type = V4L2_INPUT_TYPE_TOUCH_SENSOR;
>> -strlcpy(i->name, "Mutual References", sizeof(i->name));
>> +
>> +switch (i->index) {
>> +case MXT_V4L_INPUT_REFS:
>> +strlcpy(i->name, "Mutual References", sizeof(i->name));
>> +break;
>> +case MXT_V4L_INPUT_DELTAS:
>> +strlcpy(i->name, "Mutual Deltas", sizeof(i->name));
> 
> I don't think this name is very clear. I have no idea how to interpret 
> "Mutual"
> in this context.

"Mutual" is a touch domain specific term, it means the delta value is for
the capacitance between the horizontal and vertical lines at a particular
"node" on the touchscreen matrix, see
https://en.wikipedia.org/wiki/Touchscreen#Mutual_capacitance

I'll put in a comment.

> 
>> +break;
>> +}
>> +
>>  return 0;
>>  }
>>  
>> @@ -2337,12 +2365,16 @@ static int mxt_set_input(struct mxt_data *data, 
>> unsigned int i)
>>  {
>>  struct v4l2_pix_format *f = >dbg.format;
>>  
>> -if (i > 0)
>> +if (i >= MXT_V4L_INPUT_MAX)
>>  return -EINVAL;
>>  
>> +if (i == MXT_V4L_INPUT_DELTAS)
>> +f->pixelformat = V4L2_PIX_FMT_YS16;
>> +else
>> +f->pixelformat = V4L2_PIX_FMT_Y16;
> 
> You probably need a V4L2_TOUCH_FMT_U16 or something for this as well. It 
> certainly
> needs to be documented.

OK, will change this.

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v4 1/9] [media] Add signed 16-bit pixel format

2016-06-20 Thread Nick Dyer
Hi Hans-

On 20/06/2016 12:00, Hans Verkuil wrote:
> On 06/17/2016 04:16 PM, Nick Dyer wrote:
>> This will be used for output of raw touch delta data. This format is
>> used by Atmel maXTouch (atmel_mxt_ts) and also Synaptics RMI4.
>>
>> Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
>> ---
>>  Documentation/DocBook/media/v4l/pixfmt-ys16.xml | 79 
>> +
>>  Documentation/DocBook/media/v4l/pixfmt.xml  |  1 +
>>  drivers/media/v4l2-core/v4l2-ioctl.c|  1 +
>>  include/uapi/linux/videodev2.h  |  1 +
>>  4 files changed, 82 insertions(+)
>>  create mode 100644 Documentation/DocBook/media/v4l/pixfmt-ys16.xml
>>
>> diff --git a/Documentation/DocBook/media/v4l/pixfmt-ys16.xml 
>> b/Documentation/DocBook/media/v4l/pixfmt-ys16.xml
>> new file mode 100644
>> index 000..f92d65e
>> --- /dev/null
>> +++ b/Documentation/DocBook/media/v4l/pixfmt-ys16.xml
>> @@ -0,0 +1,79 @@
>> +
>> +  
>> +V4L2_PIX_FMT_YS16 ('YS16')
>> +
>> +  
>> +  
>> +V4L2_PIX_FMT_YS16
>> +Grey-scale image
>> +  
>> +  
>> +Description
>> +
>> +This is a signed grey-scale image with a depth of 16 bits per
>> +pixel. The most significant byte is stored at higher memory addresses
>> +(little-endian).
> 
> This is too generic. I think something like V4L2_TOUCH_FMT_DELTA_S16 is much
> more appropriate since this is neither luma (Y) data nor a picture in the
> classic sense. Since we already use V4L2_SDR_FMT_* defines for software 
> defined
> radio formats, it makes sense to use V4L2_TOUCH_FMT_* for these touch panel
> formats.

OK, that sounds sensible to me.

> The description can be based around what you told here:
> 
> https://lkml.org/lkml/2016/5/27/278
> 
> It's also important that you clearly state what the delta is against. A delta
> implies a difference from something, but what that something is isn't 
> explained.

To explain, in PCAP capacitive touch, a touch input is determined by
comparing the raw capacitance measurement to a no-touch reference (or
"baseline") measurement. Hence:

Delta = Raw - Reference

The reference measurement takes account of variations in the capacitance
characteristics across the nodes of the touch sensor, for example
manufacturing irregularities or edge effects.

I'll put something about this in the docs.

> I'm sorry for being pedantic about this, but it should be possible to make an
> application that can correctly interpret this data based on this format
> description. Otherwise there would be no point in documenting this...

No problem: thanks for your clear feedback.

--
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 v4 0/9] Output raw touch data via V4L2

2016-06-17 Thread Nick Dyer
This is a series of patches to add output of raw touch diagnostic data via V4L2
to the Atmel maXTouch and Synaptics RMI4 drivers.

It's a rewrite of the previous implementation which output via debugfs: it now
uses a V4L2 device in a similar way to the sur40 driver.

We have a utility which can read the data and display it in a useful format:
https://github.com/ndyer/heatmap/commits/heatmap-v4l

These patches are also available from
https://github.com/ndyer/linux/commits/v4l-touch-2016-06-17

Changes in v4:
- Address nits from the input side in atmel_mxt_ts patches (Dmitry Torokhov)
- Add Synaptics RMI4 F54 support patch

Changes in v3:
- Address V4L2 review comments from Hans Verkuil
- Run v4l-compliance and fix all issues - needs minor patch here:
  https://github.com/ndyer/v4l-utils/commit/cf50469773f

Changes in v2:
- Split pixfmt changes into separate commit and add DocBook
- Introduce VFL_TYPE_TOUCH_SENSOR and /dev/v4l-touch
- Remove "single node" support for now, it may be better to treat it as 
metadata later
- Explicitly set VFL_DIR_RX
- Fix Kconfig

--
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 v4 4/9] Input: atmel_mxt_ts - output diagnostic debug via v4l2 device

2016-06-17 Thread Nick Dyer
Register a video device to output T37 diagnostic data.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/Kconfig|   6 +-
 drivers/input/touchscreen/atmel_mxt_ts.c | 244 +++
 2 files changed, 248 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index da96ecf..7c1c5ec 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -117,9 +117,11 @@ config TOUCHSCREEN_ATMEL_MXT
 
 config TOUCHSCREEN_ATMEL_MXT_T37
bool "Support T37 Diagnostic Data"
-   depends on TOUCHSCREEN_ATMEL_MXT
+   depends on TOUCHSCREEN_ATMEL_MXT && VIDEO_V4L2
+   select VIDEOBUF2_VMALLOC
help
- Say Y here if you want support for the T37 Diagnostic Data object.
+ Say Y here if you want support to output data from the T37
+ Diagnostic Data object using a V4L device.
 
 config TOUCHSCREEN_AUO_PIXCIR
tristate "AUO in-cell touchscreen using Pixcir ICs"
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 0048233..3a7f705 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -28,6 +28,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 /* Firmware files */
 #define MXT_FW_NAME"maxtouch.fw"
@@ -224,6 +228,23 @@ struct mxt_dbg {
struct t37_debug *t37_buf;
unsigned int t37_pages;
unsigned int t37_nodes;
+
+   struct v4l2_device v4l2;
+   struct v4l2_pix_format format;
+   struct video_device vdev;
+   struct vb2_queue queue;
+   struct mutex lock;
+   int input;
+};
+
+static const struct v4l2_file_operations mxt_video_fops = {
+   .owner = THIS_MODULE,
+   .open = v4l2_fh_open,
+   .release = vb2_fop_release,
+   .unlocked_ioctl = video_ioctl2,
+   .read = vb2_fop_read,
+   .mmap = vb2_fop_mmap,
+   .poll = vb2_fop_poll,
 };
 
 /* Each client has this additional data */
@@ -279,6 +300,11 @@ struct mxt_data {
struct completion crc_completion;
 };
 
+struct mxt_vb2_buffer {
+   struct vb2_buffer   vb;
+   struct list_headlist;
+};
+
 static size_t mxt_obj_size(const struct mxt_object *obj)
 {
return obj->size_minus_one + 1;
@@ -1525,6 +1551,11 @@ static void mxt_free_input_device(struct mxt_data *data)
 
 static void mxt_free_object_table(struct mxt_data *data)
 {
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+   video_unregister_device(>dbg.vdev);
+   v4l2_device_unregister(>dbg.v4l2);
+#endif
+
kfree(data->object_table);
data->object_table = NULL;
kfree(data->msg_buf);
@@ -2157,10 +2188,191 @@ wait_cmd:
return mxt_convert_debug_pages(data, outbuf);
 }
 
+static int mxt_queue_setup(struct vb2_queue *q,
+  unsigned int *nbuffers, unsigned int *nplanes,
+  unsigned int sizes[], void *alloc_ctxs[])
+{
+   struct mxt_data *data = q->drv_priv;
+   size_t size = data->dbg.t37_nodes * sizeof(u16);
+
+   if (*nplanes)
+   return sizes[0] < size ? -EINVAL : 0;
+
+   *nplanes = 1;
+   sizes[0] = size;
+
+   return 0;
+}
+
+static void mxt_buffer_queue(struct vb2_buffer *vb)
+{
+   struct mxt_data *data = vb2_get_drv_priv(vb->vb2_queue);
+   u16 *ptr;
+   int ret;
+
+   ptr = vb2_plane_vaddr(vb, 0);
+   if (!ptr) {
+   dev_err(>client->dev, "Error acquiring frame ptr\n");
+   goto fault;
+   }
+
+   ret = mxt_read_diagnostic_debug(data, MXT_DIAGNOSTIC_DELTAS, ptr);
+   if (ret)
+   goto fault;
+
+   vb2_set_plane_payload(vb, 0, data->dbg.t37_nodes * sizeof(u16));
+   vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+   return;
+
+fault:
+   vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+}
+
+/* V4L2 structures */
+static const struct vb2_ops mxt_queue_ops = {
+   .queue_setup= mxt_queue_setup,
+   .buf_queue  = mxt_buffer_queue,
+   .wait_prepare   = vb2_ops_wait_prepare,
+   .wait_finish= vb2_ops_wait_finish,
+};
+
+static const struct vb2_queue mxt_queue = {
+   .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+   .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ,
+   .buf_struct_size = sizeof(struct mxt_vb2_buffer),
+   .ops = _queue_ops,
+   .mem_ops = _vmalloc_memops,
+   .timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC,
+   .min_buffers_needed = 1,
+};
+
+static int mxt_vidioc_querycap(struct file *file, void *priv,
+struct v4l2_capability *cap)
+{
+   struct mxt_data *data = video_drvdata(file);
+
+   strlcpy(cap->driver, "atmel_mxt_ts", sizeof(cap->driver));
+ 

[PATCH v4 9/9] Input: synaptics-rmi4 - add support for F54 diagnostics

2016-06-17 Thread Nick Dyer
Function 54 implements access to various RMI4 diagnostic features.

This patch adds support for retrieving this data. It registers a V4L2
device to output the data to user space.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/rmi4/Kconfig  |  11 +
 drivers/input/rmi4/Makefile |   1 +
 drivers/input/rmi4/rmi_bus.c|   3 +
 drivers/input/rmi4/rmi_driver.h |   1 +
 drivers/input/rmi4/rmi_f54.c| 743 
 5 files changed, 759 insertions(+)
 create mode 100644 drivers/input/rmi4/rmi_f54.c

diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
index f73df24..f3418b6 100644
--- a/drivers/input/rmi4/Kconfig
+++ b/drivers/input/rmi4/Kconfig
@@ -61,3 +61,14 @@ config RMI4_F30
 
  Function 30 provides GPIO and LED support for RMI4 devices. This
  includes support for buttons on TouchPads and ClickPads.
+
+config RMI4_F54
+   bool "RMI4 Function 54 (Analog diagnostics)"
+   depends on RMI4_CORE
+   depends on VIDEO_V4L2
+   select VIDEOBUF2_VMALLOC
+   help
+ Say Y here if you want to add support for RMI4 function 54
+
+ Function 54 provides access to various diagnostic features in certain
+ RMI4 touch sensors.
diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index 95c00a7..0bafc85 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -7,6 +7,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
+rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 
 # Transports
 obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o
diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index b368b05..3aedc65 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -315,6 +315,9 @@ static struct rmi_function_handler *fn_handlers[] = {
 #ifdef CONFIG_RMI4_F30
_f30_handler,
 #endif
+#ifdef CONFIG_RMI4_F54
+   _f54_handler,
+#endif
 };
 
 static void __rmi_unregister_function_handlers(int start_idx)
diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
index 6e140fa..8dfbebe 100644
--- a/drivers/input/rmi4/rmi_driver.h
+++ b/drivers/input/rmi4/rmi_driver.h
@@ -102,4 +102,5 @@ extern struct rmi_function_handler rmi_f01_handler;
 extern struct rmi_function_handler rmi_f11_handler;
 extern struct rmi_function_handler rmi_f12_handler;
 extern struct rmi_function_handler rmi_f30_handler;
+extern struct rmi_function_handler rmi_f54_handler;
 #endif
diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c
new file mode 100644
index 000..bd06788
--- /dev/null
+++ b/drivers/input/rmi4/rmi_f54.c
@@ -0,0 +1,743 @@
+/*
+ * Copyright (c) 2012-2015 Synaptics Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "rmi_driver.h"
+
+#define F54_NAME   "rmi4_f54"
+
+/* F54 data offsets */
+#define F54_REPORT_DATA_OFFSET  3
+#define F54_FIFO_OFFSET 1
+#define F54_NUM_TX_OFFSET   1
+#define F54_NUM_RX_OFFSET   0
+
+/* F54 commands */
+#define F54_GET_REPORT  1
+#define F54_FORCE_CAL   2
+
+/* Fixed sizes of reports */
+#define F54_QUERY_LEN  27
+#define F54_FULL_RAW_CAP_MIN_MAX_SIZE   4
+#define F54_HIGH_RESISTANCE_SIZE(rx, tx) \
+   (2 * ((rx) * (tx) + (rx) + (tx) + 3))
+#define F54_MAX_REPORT_SIZE(rx, tx)F54_HIGH_RESISTANCE_SIZE((rx), (tx))
+
+/* F54 capabilities */
+#define F54_CAP_BASELINE   (1 << 2)
+#define F54_CAP_IMAGE8 (1 << 3)
+#define F54_CAP_IMAGE16(1 << 6)
+
+enum f54_report_type {
+   F54_REPORT_NONE = 0,
+   F54_8BIT_IMAGE = 1,
+   F54_16BIT_IMAGE = 2,
+   F54_RAW_16BIT_IMAGE = 3,
+   F54_HIGH_RESISTANCE = 4,
+   F54_TX_TO_TX_SHORT = 5,
+   F54_RX_TO_RX1 = 7,
+   F54_TRUE_BASELINE = 9,
+   F54_FULL_RAW_CAP_MIN_MAX = 13,
+   F54_RX_OPENS1 = 14,
+   F54_TX_OPEN = 15,
+   F54_TX_TO_GROUND = 16,
+   F54_RX_TO_RX2 = 17,
+   F54_RX_OPENS2 = 18,
+   F54_FULL_RAW_CAP = 19,
+   F54_FULL_RAW_CAP_RX_COUPLING_COMP = 20,
+   F54_MAX_REPORT_TYPE,
+};
+
+struct f54_data {
+   struct rmi_function *fn;
+
+   u8 qry[F54_QUERY_LEN];
+   u8 num_rx_electrodes;
+   u8 num_tx_electrodes;
+   u8 capabilities;
+   u16 clock_rate;
+   u8 family;
+
+   enum f54_report_type report_type;
+   u8 *report_data;
+   int report_size;
+
+   bool is_busy;
+   struct mutex status_mutex;
+   struct mutex data_mutex;
+
+   

[PATCH v4 5/9] Input: atmel_mxt_ts - read touchscreen size

2016-06-17 Thread Nick Dyer
The touchscreen may have a margin where not all the matrix is used. Read
the parameters from T9 and T100 and take account of the difference.

Note: this does not read the XORIGIN/YORIGIN fields so it assumes that
the touchscreen starts at (0,0)

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 42 +++-
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 3a7f705..3c5b7d3 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -103,6 +103,8 @@ struct t7_config {
 
 /* MXT_TOUCH_MULTI_T9 field */
 #define MXT_T9_CTRL0
+#define MXT_T9_XSIZE   3
+#define MXT_T9_YSIZE   4
 #define MXT_T9_ORIENT  9
 #define MXT_T9_RANGE   18
 
@@ -150,7 +152,9 @@ struct t37_debug {
 #define MXT_T100_CTRL  0
 #define MXT_T100_CFG1  1
 #define MXT_T100_TCHAUX3
+#define MXT_T100_XSIZE 9
 #define MXT_T100_XRANGE13
+#define MXT_T100_YSIZE 20
 #define MXT_T100_YRANGE24
 
 #define MXT_T100_CFG_SWITCHXY  BIT(5)
@@ -259,6 +263,8 @@ struct mxt_data {
unsigned int max_x;
unsigned int max_y;
bool xy_switch;
+   u8 xsize;
+   u8 ysize;
bool in_bootloader;
u16 mem_size;
u8 t100_aux_ampl;
@@ -1714,6 +1720,18 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return -EINVAL;
 
error = __mxt_read_reg(client,
+  object->start_address + MXT_T9_XSIZE,
+  sizeof(data->xsize), >xsize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T9_YSIZE,
+  sizeof(data->ysize), >ysize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
   object->start_address + MXT_T9_RANGE,
   sizeof(range), );
if (error)
@@ -1763,6 +1781,18 @@ static int mxt_read_t100_config(struct mxt_data *data)
 
data->max_y = get_unaligned_le16(_y);
 
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T100_XSIZE,
+  sizeof(data->xsize), >xsize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T100_YSIZE,
+  sizeof(data->ysize), >ysize);
+   if (error)
+   return error;
+
/* read orientation config */
error =  __mxt_read_reg(client,
object->start_address + MXT_T100_CFG1,
@@ -2121,7 +2151,7 @@ static int mxt_convert_debug_pages(struct mxt_data *data, 
u16 *outbuf)
outbuf[i] = mxt_get_debug_value(data, x, y);
 
/* Next value */
-   if (++x >= data->info.matrix_xsize) {
+   if (++x >= data->xsize) {
x = 0;
y++;
}
@@ -2276,8 +2306,8 @@ static int mxt_set_input(struct mxt_data *data, unsigned 
int i)
if (i > 0)
return -EINVAL;
 
-   f->width = data->info.matrix_xsize;
-   f->height = data->info.matrix_ysize;
+   f->width = data->xsize;
+   f->height = data->ysize;
f->pixelformat = V4L2_PIX_FMT_YS16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
@@ -2392,9 +2422,9 @@ static void mxt_debug_init(struct mxt_data *data)
dbg->t37_address = object->start_address;
 
/* Calculate size of data and allocate buffer */
-   dbg->t37_nodes = data->info.matrix_xsize * data->info.matrix_ysize;
-   dbg->t37_pages = DIV_ROUND_UP(dbg->t37_nodes * sizeof(u16),
- sizeof(dbg->t37_buf->data));
+   dbg->t37_nodes = data->xsize * data->ysize;
+   dbg->t37_pages = DIV_ROUND_UP(data->xsize * data->info.matrix_ysize *
+ sizeof(u16), sizeof(dbg->t37_buf->data));
 
dbg->t37_buf = devm_kmalloc_array(>client->dev, dbg->t37_pages,
  sizeof(struct t37_debug), GFP_KERNEL);
-- 
2.5.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


[PATCH v4 7/9] Input: atmel_mxt_ts - add diagnostic data support for mXT1386

2016-06-17 Thread Nick Dyer
The mXT1386 family of chips have a different architecture which splits
the diagnostic data into 3 columns.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 31 ---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2a03636..5281325d 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -137,6 +137,10 @@ struct t9_range {
 #define MXT_DIAGNOSTIC_DELTAS  0x10
 #define MXT_DIAGNOSTIC_SIZE128
 
+#define MXT_FAMILY_1386160
+#define MXT1386_COLUMNS3
+#define MXT1386_PAGES_PER_COLUMN   8
+
 struct t37_debug {
 #ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
u8 mode;
@@ -2140,13 +2144,27 @@ recheck:
 static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
   unsigned int y)
 {
+   struct mxt_info *info = >info;
struct mxt_dbg *dbg = >dbg;
unsigned int ofs, page;
+   unsigned int col = 0;
+   unsigned int col_width;
+
+   if (info->family_id == MXT_FAMILY_1386) {
+   col_width = info->matrix_ysize / MXT1386_COLUMNS;
+   col = y / col_width;
+   y = y % col_width;
+   } else {
+   col_width = info->matrix_ysize;
+   }
 
-   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   ofs = (y + (x * col_width)) * sizeof(u16);
page = ofs / MXT_DIAGNOSTIC_SIZE;
ofs %= MXT_DIAGNOSTIC_SIZE;
 
+   if (info->family_id == MXT_FAMILY_1386)
+   page += col * MXT1386_PAGES_PER_COLUMN;
+
return get_unaligned_le16(>t37_buf[page].data[ofs]);
 }
 
@@ -2416,6 +2434,7 @@ static const struct video_device mxt_video_device = {
 
 static void mxt_debug_init(struct mxt_data *data)
 {
+   struct mxt_info *info = >info;
struct mxt_dbg *dbg = >dbg;
struct mxt_object *object;
int error;
@@ -2439,8 +2458,14 @@ static void mxt_debug_init(struct mxt_data *data)
 
/* Calculate size of data and allocate buffer */
dbg->t37_nodes = data->xsize * data->ysize;
-   dbg->t37_pages = DIV_ROUND_UP(data->xsize * data->info.matrix_ysize *
- sizeof(u16), sizeof(dbg->t37_buf->data));
+
+   if (info->family_id == MXT_FAMILY_1386)
+   dbg->t37_pages = MXT1386_COLUMNS * MXT1386_PAGES_PER_COLUMN;
+   else
+   dbg->t37_pages = DIV_ROUND_UP(data->xsize *
+ data->info.matrix_ysize *
+ sizeof(u16),
+ sizeof(dbg->t37_buf->data));
 
dbg->t37_buf = devm_kmalloc_array(>client->dev, dbg->t37_pages,
  sizeof(struct t37_debug), GFP_KERNEL);
-- 
2.5.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


[PATCH v4 2/9] [media] v4l2-core: Add VFL_TYPE_TOUCH_SENSOR

2016-06-17 Thread Nick Dyer
Some touch controllers send out raw touch data in a similar way to a
greyscale frame grabber. Add a new device type for these devices.

Use a new device prefix v4l-touch for these devices, to stop generic
capture software from treating them as webcams.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/sur40.c|  4 ++--
 drivers/media/v4l2-core/v4l2-dev.c   | 13 ++---
 drivers/media/v4l2-core/v4l2-ioctl.c | 15 ++-
 include/media/v4l2-dev.h |  3 ++-
 include/uapi/linux/videodev2.h   |  1 +
 5 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/drivers/input/touchscreen/sur40.c 
b/drivers/input/touchscreen/sur40.c
index 880c40b..2daa786 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -599,7 +599,7 @@ static int sur40_probe(struct usb_interface *interface,
sur40->vdev.queue = >queue;
video_set_drvdata(>vdev, sur40);
 
-   error = video_register_device(>vdev, VFL_TYPE_GRABBER, -1);
+   error = video_register_device(>vdev, VFL_TYPE_TOUCH_SENSOR, -1);
if (error) {
dev_err(>dev,
"Unable to register video subdevice.");
@@ -763,7 +763,7 @@ static int sur40_vidioc_enum_input(struct file *file, void 
*priv,
 {
if (i->index != 0)
return -EINVAL;
-   i->type = V4L2_INPUT_TYPE_CAMERA;
+   i->type = V4L2_INPUT_TYPE_TOUCH_SENSOR;
i->std = V4L2_STD_UNKNOWN;
strlcpy(i->name, "In-Cell Sensor", sizeof(i->name));
i->capabilities = 0;
diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index 70b559d..7068e12 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -529,6 +529,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR;
bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
+   bool is_touch = vdev->vfl_type == VFL_TYPE_TOUCH_SENSOR;
 
bitmap_zero(valid_ioctls, BASE_VIDIOC_PRIVATE);
 
@@ -573,7 +574,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
if (ops->vidioc_enum_freq_bands || ops->vidioc_g_tuner || 
ops->vidioc_g_modulator)
set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls);
 
-   if (is_vid) {
+   if (is_vid || is_touch) {
/* video specific ioctls */
if ((is_rx && (ops->vidioc_enum_fmt_vid_cap ||
   ops->vidioc_enum_fmt_vid_cap_mplane ||
@@ -662,7 +663,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
}
 
-   if (is_vid || is_vbi || is_sdr) {
+   if (is_vid || is_vbi || is_sdr || is_touch) {
/* ioctls valid for video, vbi or sdr */
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
@@ -675,7 +676,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
}
 
-   if (is_vid || is_vbi) {
+   if (is_vid || is_vbi || is_touch) {
/* ioctls valid for video or vbi */
if (ops->vidioc_s_std)
set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
@@ -739,6 +740,7 @@ static int video_register_media_controller(struct 
video_device *vdev, int type)
vdev->entity.function = MEDIA_ENT_F_UNKNOWN;
 
switch (type) {
+   case VFL_TYPE_TOUCH_SENSOR:
case VFL_TYPE_GRABBER:
intf_type = MEDIA_INTF_T_V4L_VIDEO;
vdev->entity.function = MEDIA_ENT_F_IO_V4L;
@@ -845,6 +847,8 @@ static int video_register_media_controller(struct 
video_device *vdev, int type)
  * %VFL_TYPE_SUBDEV - A subdevice
  *
  * %VFL_TYPE_SDR - Software Defined Radio
+ *
+ * %VFL_TYPE_TOUCH_SENSOR - A touch sensor
  */
 int __video_register_device(struct video_device *vdev, int type, int nr,
int warn_if_nr_in_use, struct module *owner)
@@ -888,6 +892,9 @@ int __video_register_device(struct video_device *vdev, int 
type, int nr,
/* Use device name 'swradio' because 'sdr' was already taken. */
name_base = "swradio";
break;
+   case VFL_TYPE_TOUCH_SENSOR:
+   name_base = "v4l-touch";
+   break;
default:
printk(KERN_ERR "%s called with unknown type: %d\n",
   __func__, type);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index ecf7e0b..352c4d0 100644
--- a/drivers/media/v4l2-core/v

[PATCH v4 6/9] Input: atmel_mxt_ts - handle diagnostic data orientation

2016-06-17 Thread Nick Dyer
Invert the diagnostic data to match the orientation of the input device.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 26 +-
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 3c5b7d3..2a03636 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -125,6 +125,8 @@ struct t9_range {
 
 /* MXT_TOUCH_MULTI_T9 orient */
 #define MXT_T9_ORIENT_SWITCH   (1 << 0)
+#define MXT_T9_ORIENT_INVERTX  (1 << 1)
+#define MXT_T9_ORIENT_INVERTY  (1 << 2)
 
 /* MXT_SPT_COMMSCONFIG_T18 */
 #define MXT_COMMS_CTRL 0
@@ -158,6 +160,8 @@ struct t37_debug {
 #define MXT_T100_YRANGE24
 
 #define MXT_T100_CFG_SWITCHXY  BIT(5)
+#define MXT_T100_CFG_INVERTY   BIT(6)
+#define MXT_T100_CFG_INVERTX   BIT(7)
 
 #define MXT_T100_TCHAUX_VECT   BIT(0)
 #define MXT_T100_TCHAUX_AMPL   BIT(1)
@@ -262,6 +266,8 @@ struct mxt_data {
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
+   bool invertx;
+   bool inverty;
bool xy_switch;
u8 xsize;
u8 ysize;
@@ -1747,6 +1753,8 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return error;
 
data->xy_switch = orient & MXT_T9_ORIENT_SWITCH;
+   data->invertx = orient & MXT_T9_ORIENT_INVERTX;
+   data->inverty = orient & MXT_T9_ORIENT_INVERTY;
 
return 0;
 }
@@ -1801,6 +1809,8 @@ static int mxt_read_t100_config(struct mxt_data *data)
return error;
 
data->xy_switch = cfg & MXT_T100_CFG_SWITCHXY;
+   data->invertx = cfg & MXT_T100_CFG_INVERTX;
+   data->inverty = cfg & MXT_T100_CFG_INVERTY;
 
/* allocate aux bytes */
error =  __mxt_read_reg(client,
@@ -2145,13 +2155,19 @@ static int mxt_convert_debug_pages(struct mxt_data 
*data, u16 *outbuf)
struct mxt_dbg *dbg = >dbg;
unsigned int x = 0;
unsigned int y = 0;
-   unsigned int i;
+   unsigned int i, rx, ry;
 
for (i = 0; i < dbg->t37_nodes; i++) {
-   outbuf[i] = mxt_get_debug_value(data, x, y);
+   /* Handle orientation */
+   rx = data->xy_switch ? y : x;
+   ry = data->xy_switch ? x : y;
+   rx = data->invertx ? (data->xsize - 1 - rx) : rx;
+   ry = data->inverty ? (data->ysize - 1 - ry) : ry;
+
+   outbuf[i] = mxt_get_debug_value(data, rx, ry);
 
/* Next value */
-   if (++x >= data->xsize) {
+   if (++x >= (data->xy_switch ? data->ysize : data->xsize)) {
x = 0;
y++;
}
@@ -2306,8 +2322,8 @@ static int mxt_set_input(struct mxt_data *data, unsigned 
int i)
if (i > 0)
return -EINVAL;
 
-   f->width = data->xsize;
-   f->height = data->ysize;
+   f->width = data->xy_switch ? data->ysize : data->xsize;
+   f->height = data->xy_switch ? data->xsize : data->ysize;
f->pixelformat = V4L2_PIX_FMT_YS16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
-- 
2.5.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


[PATCH v4 8/9] Input: atmel_mxt_ts - add support for reference data

2016-06-17 Thread Nick Dyer
There are different datatypes available from a maXTouch chip. Add
support to retrieve reference data as well.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 58 
 1 file changed, 51 insertions(+), 7 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 5281325d..bb01fb0 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -135,6 +135,7 @@ struct t9_range {
 /* MXT_DEBUG_DIAGNOSTIC_T37 */
 #define MXT_DIAGNOSTIC_PAGEUP  0x01
 #define MXT_DIAGNOSTIC_DELTAS  0x10
+#define MXT_DIAGNOSTIC_REFS0x11
 #define MXT_DIAGNOSTIC_SIZE128
 
 #define MXT_FAMILY_1386160
@@ -249,6 +250,12 @@ struct mxt_dbg {
int input;
 };
 
+enum v4l_dbg_inputs {
+   MXT_V4L_INPUT_DELTAS,
+   MXT_V4L_INPUT_REFS,
+   MXT_V4L_INPUT_MAX,
+};
+
 static const struct v4l2_file_operations mxt_video_fops = {
.owner = THIS_MODULE,
.open = v4l2_fh_open,
@@ -2273,6 +2280,7 @@ static void mxt_buffer_queue(struct vb2_buffer *vb)
struct mxt_data *data = vb2_get_drv_priv(vb->vb2_queue);
u16 *ptr;
int ret;
+   u8 mode;
 
ptr = vb2_plane_vaddr(vb, 0);
if (!ptr) {
@@ -2280,7 +2288,18 @@ static void mxt_buffer_queue(struct vb2_buffer *vb)
goto fault;
}
 
-   ret = mxt_read_diagnostic_debug(data, MXT_DIAGNOSTIC_DELTAS, ptr);
+   switch (data->dbg.input) {
+   case MXT_V4L_INPUT_DELTAS:
+   default:
+   mode = MXT_DIAGNOSTIC_DELTAS;
+   break;
+
+   case MXT_V4L_INPUT_REFS:
+   mode = MXT_DIAGNOSTIC_REFS;
+   break;
+   }
+
+   ret = mxt_read_diagnostic_debug(data, mode, ptr);
if (ret)
goto fault;
 
@@ -2325,11 +2344,20 @@ static int mxt_vidioc_querycap(struct file *file, void 
*priv,
 static int mxt_vidioc_enum_input(struct file *file, void *priv,
   struct v4l2_input *i)
 {
-   if (i->index > 0)
+   if (i->index >= MXT_V4L_INPUT_MAX)
return -EINVAL;
 
i->type = V4L2_INPUT_TYPE_TOUCH_SENSOR;
-   strlcpy(i->name, "Mutual References", sizeof(i->name));
+
+   switch (i->index) {
+   case MXT_V4L_INPUT_REFS:
+   strlcpy(i->name, "Mutual References", sizeof(i->name));
+   break;
+   case MXT_V4L_INPUT_DELTAS:
+   strlcpy(i->name, "Mutual Deltas", sizeof(i->name));
+   break;
+   }
+
return 0;
 }
 
@@ -2337,12 +2365,16 @@ static int mxt_set_input(struct mxt_data *data, 
unsigned int i)
 {
struct v4l2_pix_format *f = >dbg.format;
 
-   if (i > 0)
+   if (i >= MXT_V4L_INPUT_MAX)
return -EINVAL;
 
+   if (i == MXT_V4L_INPUT_DELTAS)
+   f->pixelformat = V4L2_PIX_FMT_YS16;
+   else
+   f->pixelformat = V4L2_PIX_FMT_Y16;
+
f->width = data->xy_switch ? data->ysize : data->xsize;
f->height = data->xy_switch ? data->xsize : data->ysize;
-   f->pixelformat = V4L2_PIX_FMT_YS16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
f->bytesperline = f->width * sizeof(u16);
@@ -2380,10 +2412,22 @@ static int mxt_vidioc_fmt(struct file *file, void 
*priv, struct v4l2_format *f)
 static int mxt_vidioc_enum_fmt(struct file *file, void *priv,
 struct v4l2_fmtdesc *fmt)
 {
-   if (fmt->index > 0 || fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   return -EINVAL;
+
+   switch (fmt->index) {
+   case 0:
+   fmt->pixelformat = V4L2_PIX_FMT_Y16;
+   break;
+
+   case 1:
+   fmt->pixelformat = V4L2_PIX_FMT_YS16;
+   break;
+
+   default:
return -EINVAL;
+   }
 
-   fmt->pixelformat = V4L2_PIX_FMT_YS16;
return 0;
 }
 
-- 
2.5.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


[PATCH v4 1/9] [media] Add signed 16-bit pixel format

2016-06-17 Thread Nick Dyer
This will be used for output of raw touch delta data. This format is
used by Atmel maXTouch (atmel_mxt_ts) and also Synaptics RMI4.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 Documentation/DocBook/media/v4l/pixfmt-ys16.xml | 79 +
 Documentation/DocBook/media/v4l/pixfmt.xml  |  1 +
 drivers/media/v4l2-core/v4l2-ioctl.c|  1 +
 include/uapi/linux/videodev2.h  |  1 +
 4 files changed, 82 insertions(+)
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-ys16.xml

diff --git a/Documentation/DocBook/media/v4l/pixfmt-ys16.xml 
b/Documentation/DocBook/media/v4l/pixfmt-ys16.xml
new file mode 100644
index 000..f92d65e
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/pixfmt-ys16.xml
@@ -0,0 +1,79 @@
+
+  
+V4L2_PIX_FMT_YS16 ('YS16')
+
+  
+  
+V4L2_PIX_FMT_YS16
+Grey-scale image
+  
+  
+Description
+
+This is a signed grey-scale image with a depth of 16 bits per
+pixel. The most significant byte is stored at higher memory addresses
+(little-endian).
+
+
+  V4L2_PIX_FMT_YS16 4  4
+pixel image
+
+  
+   Byte Order.
+   Each cell is one byte.
+ 
+   
+ 
+ 
+   
+ start+0:
+ Y'00low
+ Y'00high
+ Y'01low
+ Y'01high
+ Y'02low
+ Y'02high
+ Y'03low
+ Y'03high
+   
+   
+ start+8:
+ Y'10low
+ Y'10high
+ Y'11low
+ Y'11high
+ Y'12low
+ Y'12high
+ Y'13low
+ Y'13high
+   
+   
+ start+16:
+ Y'20low
+ Y'20high
+ Y'21low
+ Y'21high
+ Y'22low
+ Y'22high
+ Y'23low
+ Y'23high
+   
+   
+ start+24:
+ Y'30low
+ Y'30high
+ Y'31low
+ Y'31high
+ Y'32low
+ Y'32high
+ Y'33low
+ Y'33high
+   
+ 
+   
+ 
+   
+  
+
+  
+
diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml 
b/Documentation/DocBook/media/v4l/pixfmt.xml
index 5a08aee..f3e3e6d 100644
--- a/Documentation/DocBook/media/v4l/pixfmt.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt.xml
@@ -1619,6 +1619,7 @@ information.
 
 
 
+
 
 
 
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 28e5be2..ecf7e0b 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1164,6 +1164,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_PIX_FMT_Y10:  descr = "10-bit Greyscale"; break;
case V4L2_PIX_FMT_Y12:  descr = "12-bit Greyscale"; break;
case V4L2_PIX_FMT_Y16:  descr = "16-bit Greyscale"; break;
+   case V4L2_PIX_FMT_YS16: descr = "16-bit Greyscale (Signed)"; 
break;
case V4L2_PIX_FMT_Y16_BE:   descr = "16-bit Greyscale BE"; break;
case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; 
break;
case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break;
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 8f95191..e0125cf 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -493,6 +493,7 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12  Greyscale  
   */
 #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16  Greyscale  
   */
 #define V4L2_PIX_FMT_Y16_BE  v4l2_fourcc_be('Y', '1', '6', ' ') /* 16  
Greyscale BE  */
+#define V4L2_PIX_FMT_YS16v4l2_fourcc('Y', 'S', '1', '6') /* signed 16-bit 
Greyscale */
 
 /* Grey bit-packed formats */
 #define V4L2_PIX_FMT_Y10BPACKv4l2_fourcc('Y', '1', '0', 'B') /* 10  
Greyscale bit-packed */
-- 
2.5.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


[PATCH v4 3/9] Input: atmel_mxt_ts - add support for T37 diagnostic data

2016-06-17 Thread Nick Dyer
Atmel maXTouch devices have a T37 object which can be used to read raw
touch deltas from the device. This consists of an array of 16-bit
integers, one for each node on the touchscreen matrix.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/Kconfig|   6 ++
 drivers/input/touchscreen/atmel_mxt_ts.c | 159 +++
 2 files changed, 165 insertions(+)

diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index 8ecdc38..da96ecf 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -115,6 +115,12 @@ config TOUCHSCREEN_ATMEL_MXT
  To compile this driver as a module, choose M here: the
  module will be called atmel_mxt_ts.
 
+config TOUCHSCREEN_ATMEL_MXT_T37
+   bool "Support T37 Diagnostic Data"
+   depends on TOUCHSCREEN_ATMEL_MXT
+   help
+ Say Y here if you want support for the T37 Diagnostic Data object.
+
 config TOUCHSCREEN_AUO_PIXCIR
tristate "AUO in-cell touchscreen using Pixcir ICs"
depends on I2C
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 5af7907..0048233 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -124,6 +124,19 @@ struct t9_range {
 #define MXT_COMMS_CTRL 0
 #define MXT_COMMS_CMD  1
 
+/* MXT_DEBUG_DIAGNOSTIC_T37 */
+#define MXT_DIAGNOSTIC_PAGEUP  0x01
+#define MXT_DIAGNOSTIC_DELTAS  0x10
+#define MXT_DIAGNOSTIC_SIZE128
+
+struct t37_debug {
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+   u8 mode;
+   u8 page;
+   u8 data[MXT_DIAGNOSTIC_SIZE];
+#endif
+};
+
 /* Define for MXT_GEN_COMMAND_T6 */
 #define MXT_BOOT_VALUE 0xa5
 #define MXT_RESET_VALUE0x01
@@ -205,6 +218,14 @@ struct mxt_object {
u8 num_report_ids;
 } __packed;
 
+struct mxt_dbg {
+   u16 t37_address;
+   u16 diag_cmd_address;
+   struct t37_debug *t37_buf;
+   unsigned int t37_pages;
+   unsigned int t37_nodes;
+};
+
 /* Each client has this additional data */
 struct mxt_data {
struct i2c_client *client;
@@ -233,6 +254,7 @@ struct mxt_data {
u8 num_touchids;
u8 multitouch;
struct t7_config t7_cfg;
+   struct mxt_dbg dbg;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -2043,6 +2065,141 @@ recheck:
return 0;
 }
 
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37
+static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
+  unsigned int y)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int ofs, page;
+
+   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   page = ofs / MXT_DIAGNOSTIC_SIZE;
+   ofs %= MXT_DIAGNOSTIC_SIZE;
+
+   return get_unaligned_le16(>t37_buf[page].data[ofs]);
+}
+
+static int mxt_convert_debug_pages(struct mxt_data *data, u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int x = 0;
+   unsigned int y = 0;
+   unsigned int i;
+
+   for (i = 0; i < dbg->t37_nodes; i++) {
+   outbuf[i] = mxt_get_debug_value(data, x, y);
+
+   /* Next value */
+   if (++x >= data->info.matrix_xsize) {
+   x = 0;
+   y++;
+   }
+   }
+
+   return 0;
+}
+
+static int mxt_read_diagnostic_debug(struct mxt_data *data, u8 mode,
+u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   int retries = 0;
+   int page;
+   int ret;
+   u8 cmd = mode;
+   struct t37_debug *p;
+   u8 cmd_poll;
+
+   for (page = 0; page < dbg->t37_pages; page++) {
+   p = dbg->t37_buf + page;
+
+   ret = mxt_write_reg(data->client, dbg->diag_cmd_address,
+   cmd);
+   if (ret)
+   return ret;
+
+   retries = 0;
+   msleep(20);
+wait_cmd:
+   /* Read back command byte */
+   ret = __mxt_read_reg(data->client, dbg->diag_cmd_address,
+sizeof(cmd_poll), _poll);
+   if (ret)
+   return ret;
+
+   /* Field is cleared once the command has been processed */
+   if (cmd_poll) {
+   if (retries++ > 100)
+   return -EINVAL;
+
+   msleep(20);
+   goto wait_cmd;
+   }
+
+   /* Read T37 page */
+   ret = __mxt_read_reg(data->client, dbg->t37_address,
+sizeof(struct t37_debug), p);
+   if (ret)
+   return ret;
+
+   if (p->mode != mode || p->page != page) {
+  

Re: [PATCH v3 0/8] Input: atmel_mxt_ts - output raw touch diagnostic data via V4L

2016-06-13 Thread Nick Dyer
On 02/06/2016 16:14, Nick Dyer wrote:
> On 01/06/2016 19:17, Dmitry Torokhov wrote:
>> On Wed, Jun 01, 2016 at 05:39:44PM +0100, Nick Dyer wrote:
>>> This is a series of patches to add diagnostic data support to the Atmel
>>> maXTouch driver. It's a rewrite of the previous implementation which output 
>>> via
>>> debugfs: it now uses a V4L2 device in a similar way to the sur40 driver.
>>
>> I do not have any objections other than some nits form the input side;
>> majority of the review should come from V4L2 side here...
> 
> Thanks for the review. I've hopefully fixed the issues you raised and
> pushed it to
> https://github.com/ndyer/linux/commits/diagnostic-v4l-20160602
> 
> I will wait for the V4L2 folks to comment before posting a [PATCH v4]

Hi Hans-

I've done a bit of further work on this now, so unless you have any
conerns, I'm going to post an update to the patch set in the next couple of
days.

cheers

Nick
--
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 0/8] Input: atmel_mxt_ts - output raw touch diagnostic data via V4L

2016-06-02 Thread Nick Dyer
Hi Dmitry-

On 01/06/2016 19:17, Dmitry Torokhov wrote:
> On Wed, Jun 01, 2016 at 05:39:44PM +0100, Nick Dyer wrote:
>> This is a series of patches to add diagnostic data support to the Atmel
>> maXTouch driver. It's a rewrite of the previous implementation which output 
>> via
>> debugfs: it now uses a V4L2 device in a similar way to the sur40 driver.
>
> I do not have any objections other than some nits form the input side;
> majority of the review should come from V4L2 side here...

Thanks for the review. I've hopefully fixed the issues you raised and
pushed it to
https://github.com/ndyer/linux/commits/diagnostic-v4l-20160602

I will wait for the V4L2 folks to comment before posting a [PATCH v4]

cheers

Nick
--
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 v3 0/8] Input: atmel_mxt_ts - output raw touch diagnostic data via V4L

2016-06-01 Thread Nick Dyer
This is a series of patches to add diagnostic data support to the Atmel
maXTouch driver. It's a rewrite of the previous implementation which output via
debugfs: it now uses a V4L2 device in a similar way to the sur40 driver.

There are significant performance advantages to putting this code into the
driver.  The algorithm for retrieving the data has been fairly consistent
across a range of chips, with the exception of the mXT1386 series (see patch).

We have a utility which can read the data and display it in a useful format:
https://github.com/ndyer/heatmap/commits/heatmap-v4l

These patches are also available from
https://github.com/ndyer/linux/commits/diagnostic-v4l

Changes in v3:
- Address V4L2 review comments from Hans Verkuil
- Run v4l-compliance and fix all issues - needs minor patch here:
  https://github.com/ndyer/v4l-utils/commit/cf50469773f

Changes in v2:
- Split pixfmt changes into separate commit and add DocBook
- Introduce VFL_TYPE_TOUCH_SENSOR and /dev/v4l-touch
- Remove "single node" support for now, it may be better to treat it as 
metadata later
- Explicitly set VFL_DIR_RX
- Fix Kconfig

--
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 v3 6/8] Input: atmel_mxt_ts - handle diagnostic data orientation

2016-06-01 Thread Nick Dyer
Invert the diagnostic data to match the orientation of the input device.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 26 +-
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index ac4126c..eced661 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -125,6 +125,8 @@ struct t9_range {
 
 /* MXT_TOUCH_MULTI_T9 orient */
 #define MXT_T9_ORIENT_SWITCH   (1 << 0)
+#define MXT_T9_ORIENT_INVERTX  (1 << 1)
+#define MXT_T9_ORIENT_INVERTY  (1 << 2)
 
 /* MXT_SPT_COMMSCONFIG_T18 */
 #define MXT_COMMS_CTRL 0
@@ -156,6 +158,8 @@ struct t37_debug {
 #define MXT_T100_YRANGE24
 
 #define MXT_T100_CFG_SWITCHXY  BIT(5)
+#define MXT_T100_CFG_INVERTY   BIT(6)
+#define MXT_T100_CFG_INVERTX   BIT(7)
 
 #define MXT_T100_TCHAUX_VECT   BIT(0)
 #define MXT_T100_TCHAUX_AMPL   BIT(1)
@@ -260,6 +264,8 @@ struct mxt_data {
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
+   bool invertx;
+   bool inverty;
bool xy_switch;
u8 xsize;
u8 ysize;
@@ -1743,6 +1749,8 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return error;
 
data->xy_switch = orient & MXT_T9_ORIENT_SWITCH;
+   data->invertx = orient & MXT_T9_ORIENT_INVERTX;
+   data->inverty = orient & MXT_T9_ORIENT_INVERTY;
 
return 0;
 }
@@ -1797,6 +1805,8 @@ static int mxt_read_t100_config(struct mxt_data *data)
return error;
 
data->xy_switch = cfg & MXT_T100_CFG_SWITCHXY;
+   data->invertx = cfg & MXT_T100_CFG_INVERTX;
+   data->inverty = cfg & MXT_T100_CFG_INVERTY;
 
/* allocate aux bytes */
error =  __mxt_read_reg(client,
@@ -2140,13 +2150,19 @@ static int mxt_convert_debug_pages(struct mxt_data 
*data, u16 *outbuf)
struct mxt_dbg *dbg = >dbg;
unsigned int x = 0;
unsigned int y = 0;
-   unsigned int i;
+   unsigned int i, rx, ry;
 
for (i = 0; i < dbg->t37_nodes; i++) {
-   outbuf[i] = mxt_get_debug_value(data, x, y);
+   /* Handle orientation */
+   rx = data->xy_switch ? y : x;
+   ry = data->xy_switch ? x : y;
+   rx = data->invertx ? (data->xsize - 1 - rx) : rx;
+   ry = data->inverty ? (data->ysize - 1 - ry) : ry;
+
+   outbuf[i] = mxt_get_debug_value(data, rx, ry);
 
/* Next value */
-   if (++x >= data->xsize) {
+   if (++x >= (data->xy_switch ? data->ysize : data->xsize)) {
x = 0;
y++;
}
@@ -2301,8 +2317,8 @@ static int mxt_set_input(struct mxt_data *data, unsigned 
int i)
if (i > 0)
return -EINVAL;
 
-   f->width = data->xsize;
-   f->height = data->ysize;
+   f->width = data->xy_switch ? data->ysize : data->xsize;
+   f->height = data->xy_switch ? data->xsize : data->ysize;
f->pixelformat = V4L2_PIX_FMT_YS16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
-- 
2.5.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


[PATCH v3 2/8] [media] Add signed 16-bit pixel format

2016-06-01 Thread Nick Dyer
This will be used for output of raw touch delta data. This format is
used by Atmel maXTouch (atmel_mxt_ts) and also Synaptics RMI4.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 Documentation/DocBook/media/v4l/pixfmt-ys16.xml | 79 +
 Documentation/DocBook/media/v4l/pixfmt.xml  |  1 +
 drivers/media/v4l2-core/v4l2-ioctl.c|  1 +
 include/uapi/linux/videodev2.h  |  1 +
 4 files changed, 82 insertions(+)
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-ys16.xml

diff --git a/Documentation/DocBook/media/v4l/pixfmt-ys16.xml 
b/Documentation/DocBook/media/v4l/pixfmt-ys16.xml
new file mode 100644
index 000..f92d65e
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/pixfmt-ys16.xml
@@ -0,0 +1,79 @@
+
+  
+V4L2_PIX_FMT_YS16 ('YS16')
+
+  
+  
+V4L2_PIX_FMT_YS16
+Grey-scale image
+  
+  
+Description
+
+This is a signed grey-scale image with a depth of 16 bits per
+pixel. The most significant byte is stored at higher memory addresses
+(little-endian).
+
+
+  V4L2_PIX_FMT_YS16 4  4
+pixel image
+
+  
+   Byte Order.
+   Each cell is one byte.
+ 
+   
+ 
+ 
+   
+ start+0:
+ Y'00low
+ Y'00high
+ Y'01low
+ Y'01high
+ Y'02low
+ Y'02high
+ Y'03low
+ Y'03high
+   
+   
+ start+8:
+ Y'10low
+ Y'10high
+ Y'11low
+ Y'11high
+ Y'12low
+ Y'12high
+ Y'13low
+ Y'13high
+   
+   
+ start+16:
+ Y'20low
+ Y'20high
+ Y'21low
+ Y'21high
+ Y'22low
+ Y'22high
+ Y'23low
+ Y'23high
+   
+   
+ start+24:
+ Y'30low
+ Y'30high
+ Y'31low
+ Y'31high
+ Y'32low
+ Y'32high
+ Y'33low
+ Y'33high
+   
+ 
+   
+ 
+   
+  
+
+  
+
diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml 
b/Documentation/DocBook/media/v4l/pixfmt.xml
index 5a08aee..f3e3e6d 100644
--- a/Documentation/DocBook/media/v4l/pixfmt.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt.xml
@@ -1619,6 +1619,7 @@ information.
 
 
 
+
 
 
 
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 28e5be2..ecf7e0b 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1164,6 +1164,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_PIX_FMT_Y10:  descr = "10-bit Greyscale"; break;
case V4L2_PIX_FMT_Y12:  descr = "12-bit Greyscale"; break;
case V4L2_PIX_FMT_Y16:  descr = "16-bit Greyscale"; break;
+   case V4L2_PIX_FMT_YS16: descr = "16-bit Greyscale (Signed)"; 
break;
case V4L2_PIX_FMT_Y16_BE:   descr = "16-bit Greyscale BE"; break;
case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; 
break;
case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break;
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 8f95191..e0125cf 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -493,6 +493,7 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12  Greyscale  
   */
 #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16  Greyscale  
   */
 #define V4L2_PIX_FMT_Y16_BE  v4l2_fourcc_be('Y', '1', '6', ' ') /* 16  
Greyscale BE  */
+#define V4L2_PIX_FMT_YS16v4l2_fourcc('Y', 'S', '1', '6') /* signed 16-bit 
Greyscale */
 
 /* Grey bit-packed formats */
 #define V4L2_PIX_FMT_Y10BPACKv4l2_fourcc('Y', '1', '0', 'B') /* 10  
Greyscale bit-packed */
-- 
2.5.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


[PATCH v3 3/8] [media] v4l2-core: Add VFL_TYPE_TOUCH_SENSOR

2016-06-01 Thread Nick Dyer
Some touch controllers send out raw touch data in a similar way to a
greyscale frame grabber. Add a new device type for these devices.

Use a new device prefix v4l-touch for these devices, to stop generic
capture software from treating them as webcams.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/sur40.c|  2 +-
 drivers/media/v4l2-core/v4l2-dev.c   | 13 ++---
 drivers/media/v4l2-core/v4l2-ioctl.c | 15 ++-
 include/media/v4l2-dev.h |  3 ++-
 include/uapi/linux/videodev2.h   |  1 +
 5 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/drivers/input/touchscreen/sur40.c 
b/drivers/input/touchscreen/sur40.c
index 880c40b..7e5fe2b 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -599,7 +599,7 @@ static int sur40_probe(struct usb_interface *interface,
sur40->vdev.queue = >queue;
video_set_drvdata(>vdev, sur40);
 
-   error = video_register_device(>vdev, VFL_TYPE_GRABBER, -1);
+   error = video_register_device(>vdev, VFL_TYPE_TOUCH_SENSOR, -1);
if (error) {
dev_err(>dev,
"Unable to register video subdevice.");
diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index 70b559d..7068e12 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -529,6 +529,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR;
bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
+   bool is_touch = vdev->vfl_type == VFL_TYPE_TOUCH_SENSOR;
 
bitmap_zero(valid_ioctls, BASE_VIDIOC_PRIVATE);
 
@@ -573,7 +574,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
if (ops->vidioc_enum_freq_bands || ops->vidioc_g_tuner || 
ops->vidioc_g_modulator)
set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls);
 
-   if (is_vid) {
+   if (is_vid || is_touch) {
/* video specific ioctls */
if ((is_rx && (ops->vidioc_enum_fmt_vid_cap ||
   ops->vidioc_enum_fmt_vid_cap_mplane ||
@@ -662,7 +663,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
}
 
-   if (is_vid || is_vbi || is_sdr) {
+   if (is_vid || is_vbi || is_sdr || is_touch) {
/* ioctls valid for video, vbi or sdr */
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
@@ -675,7 +676,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
}
 
-   if (is_vid || is_vbi) {
+   if (is_vid || is_vbi || is_touch) {
/* ioctls valid for video or vbi */
if (ops->vidioc_s_std)
set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
@@ -739,6 +740,7 @@ static int video_register_media_controller(struct 
video_device *vdev, int type)
vdev->entity.function = MEDIA_ENT_F_UNKNOWN;
 
switch (type) {
+   case VFL_TYPE_TOUCH_SENSOR:
case VFL_TYPE_GRABBER:
intf_type = MEDIA_INTF_T_V4L_VIDEO;
vdev->entity.function = MEDIA_ENT_F_IO_V4L;
@@ -845,6 +847,8 @@ static int video_register_media_controller(struct 
video_device *vdev, int type)
  * %VFL_TYPE_SUBDEV - A subdevice
  *
  * %VFL_TYPE_SDR - Software Defined Radio
+ *
+ * %VFL_TYPE_TOUCH_SENSOR - A touch sensor
  */
 int __video_register_device(struct video_device *vdev, int type, int nr,
int warn_if_nr_in_use, struct module *owner)
@@ -888,6 +892,9 @@ int __video_register_device(struct video_device *vdev, int 
type, int nr,
/* Use device name 'swradio' because 'sdr' was already taken. */
name_base = "swradio";
break;
+   case VFL_TYPE_TOUCH_SENSOR:
+   name_base = "v4l-touch";
+   break;
default:
printk(KERN_ERR "%s called with unknown type: %d\n",
   __func__, type);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index ecf7e0b..352c4d0 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -924,6 +924,7 @@ static int check_fmt(struct file *file, enum v4l2_buf_type 
type)
bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
+   bool is_touch = vfd->vfl_type == VFL_TYPE_TOUCH_SENSOR;
bool is_rx =

[PATCH v3 4/8] Input: atmel_mxt_ts - output diagnostic debug via v4l2 device

2016-06-01 Thread Nick Dyer
Register a video device to output T37 diagnostic data.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/Kconfig|   2 +
 drivers/input/touchscreen/atmel_mxt_ts.c | 247 +++
 2 files changed, 249 insertions(+)

diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index 8ecdc38..73154b6 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -105,6 +105,8 @@ config TOUCHSCREEN_AR1021_I2C
 config TOUCHSCREEN_ATMEL_MXT
tristate "Atmel mXT I2C Touchscreen"
depends on I2C
+   depends on VIDEO_V4L2
+   select VIDEOBUF2_VMALLOC
select FW_LOADER
help
  Say Y here if you have Atmel mXT series I2C touchscreen,
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 21f42ed..8608cb1 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -28,6 +28,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 /* Firmware files */
 #define MXT_FW_NAME"maxtouch.fw"
@@ -222,6 +226,23 @@ struct mxt_dbg {
struct t37_debug *t37_buf;
unsigned int t37_pages;
unsigned int t37_nodes;
+
+   struct v4l2_device v4l2;
+   struct v4l2_pix_format format;
+   struct video_device vdev;
+   struct vb2_queue queue;
+   struct mutex lock;
+   int input;
+};
+
+static const struct v4l2_file_operations mxt_video_fops = {
+   .owner = THIS_MODULE,
+   .open = v4l2_fh_open,
+   .release = vb2_fop_release,
+   .unlocked_ioctl = video_ioctl2,
+   .read = vb2_fop_read,
+   .mmap = vb2_fop_mmap,
+   .poll = vb2_fop_poll,
 };
 
 /* Each client has this additional data */
@@ -277,6 +298,11 @@ struct mxt_data {
struct completion crc_completion;
 };
 
+struct mxt_vb2_buffer {
+   struct vb2_buffer   vb;
+   struct list_headlist;
+};
+
 static size_t mxt_obj_size(const struct mxt_object *obj)
 {
return obj->size_minus_one + 1;
@@ -1523,6 +1549,9 @@ static void mxt_free_input_device(struct mxt_data *data)
 
 static void mxt_free_object_table(struct mxt_data *data)
 {
+   video_unregister_device(>dbg.vdev);
+   v4l2_device_unregister(>dbg.v4l2);
+
kfree(data->object_table);
data->object_table = NULL;
kfree(data->msg_buf);
@@ -2154,10 +2183,191 @@ wait_cmd:
return mxt_convert_debug_pages(data, outbuf);
 }
 
+static int mxt_queue_setup(struct vb2_queue *q,
+  unsigned int *nbuffers, unsigned int *nplanes,
+  unsigned int sizes[], void *alloc_ctxs[])
+{
+   struct mxt_data *data = q->drv_priv;
+   size_t size = data->dbg.t37_nodes * sizeof(u16);
+
+   if (*nplanes)
+   return sizes[0] < size ? -EINVAL : 0;
+
+   *nplanes = 1;
+   sizes[0] = size;
+
+   return 0;
+}
+
+static void mxt_buffer_queue(struct vb2_buffer *vb)
+{
+   struct mxt_data *data = vb2_get_drv_priv(vb->vb2_queue);
+   u16 *ptr;
+   int ret;
+
+   ptr = vb2_plane_vaddr(vb, 0);
+   if (!ptr) {
+   dev_err(>client->dev, "Error acquiring frame ptr\n");
+   goto fault;
+   }
+
+   ret = mxt_read_diagnostic_debug(data, MXT_DIAGNOSTIC_DELTAS, ptr);
+   if (ret)
+   goto fault;
+
+   vb2_set_plane_payload(vb, 0, data->dbg.t37_nodes * sizeof(u16));
+   vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+   return;
+
+fault:
+   vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+}
+
+/* V4L2 structures */
+static const struct vb2_ops mxt_queue_ops = {
+   .queue_setup= mxt_queue_setup,
+   .buf_queue  = mxt_buffer_queue,
+   .wait_prepare   = vb2_ops_wait_prepare,
+   .wait_finish= vb2_ops_wait_finish,
+};
+
+static const struct vb2_queue mxt_queue = {
+   .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+   .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ,
+   .buf_struct_size = sizeof(struct mxt_vb2_buffer),
+   .ops = _queue_ops,
+   .mem_ops = _vmalloc_memops,
+   .timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC,
+   .min_buffers_needed = 1,
+};
+
+static int mxt_vidioc_querycap(struct file *file, void *priv,
+struct v4l2_capability *cap)
+{
+   struct mxt_data *data = video_drvdata(file);
+
+   strlcpy(cap->driver, "atmel_mxt_ts", sizeof(cap->driver));
+   strlcpy(cap->card, "atmel_mxt_ts touch", sizeof(cap->card));
+   snprintf(cap->bus_info, sizeof(cap->bus_info),
+"I2C:%s", dev_name(>client->dev));
+   return 0;
+}
+
+static int mxt_vidioc_enum_input(struct file *file, void *priv,
+ 

[PATCH v3 1/8] Input: atmel_mxt_ts - add support for T37 diagnostic data

2016-06-01 Thread Nick Dyer
Atmel maXTouch devices have a T37 object which can be used to read raw
touch deltas from the device. This consists of an array of 16-bit
integers, one for each node on the touchscreen matrix.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 152 +++
 1 file changed, 152 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 5af7907..21f42ed 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -124,6 +124,17 @@ struct t9_range {
 #define MXT_COMMS_CTRL 0
 #define MXT_COMMS_CMD  1
 
+/* MXT_DEBUG_DIAGNOSTIC_T37 */
+#define MXT_DIAGNOSTIC_PAGEUP  0x01
+#define MXT_DIAGNOSTIC_DELTAS  0x10
+#define MXT_DIAGNOSTIC_SIZE128
+
+struct t37_debug {
+   u8 mode;
+   u8 page;
+   u8 data[MXT_DIAGNOSTIC_SIZE];
+};
+
 /* Define for MXT_GEN_COMMAND_T6 */
 #define MXT_BOOT_VALUE 0xa5
 #define MXT_RESET_VALUE0x01
@@ -205,6 +216,14 @@ struct mxt_object {
u8 num_report_ids;
 } __packed;
 
+struct mxt_dbg {
+   u16 t37_address;
+   u16 diag_cmd_address;
+   struct t37_debug *t37_buf;
+   unsigned int t37_pages;
+   unsigned int t37_nodes;
+};
+
 /* Each client has this additional data */
 struct mxt_data {
struct i2c_client *client;
@@ -233,6 +252,7 @@ struct mxt_data {
u8 num_touchids;
u8 multitouch;
struct t7_config t7_cfg;
+   struct mxt_dbg dbg;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -2043,6 +2063,136 @@ recheck:
return 0;
 }
 
+static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
+  unsigned int y)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int ofs, page;
+
+   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   page = ofs / MXT_DIAGNOSTIC_SIZE;
+   ofs %= MXT_DIAGNOSTIC_SIZE;
+
+   return get_unaligned_le16(>t37_buf[page].data[ofs]);
+}
+
+static int mxt_convert_debug_pages(struct mxt_data *data, u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int x = 0;
+   unsigned int y = 0;
+   unsigned int i;
+
+   for (i = 0; i < dbg->t37_nodes; i++) {
+   outbuf[i] = mxt_get_debug_value(data, x, y);
+
+   /* Next value */
+   if (++x >= data->info.matrix_xsize) {
+   x = 0;
+   y++;
+   }
+   }
+
+   return 0;
+}
+
+static int mxt_read_diagnostic_debug(struct mxt_data *data, u8 mode,
+u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   int retries = 0;
+   int page;
+   int ret;
+   u8 cmd = mode;
+   struct t37_debug *p;
+   u8 cmd_poll;
+
+   for (page = 0; page < dbg->t37_pages; page++) {
+   p = dbg->t37_buf + page;
+
+   ret = mxt_write_reg(data->client, dbg->diag_cmd_address,
+   cmd);
+   if (ret)
+   return ret;
+
+   retries = 0;
+   msleep(20);
+wait_cmd:
+   /* Read back command byte */
+   ret = __mxt_read_reg(data->client, dbg->diag_cmd_address,
+sizeof(cmd_poll), _poll);
+   if (ret)
+   return ret;
+
+   /* Field is cleared once the command has been processed */
+   if (cmd_poll) {
+   if (retries++ > 100)
+   return -EINVAL;
+
+   msleep(20);
+   goto wait_cmd;
+   }
+
+   /* Read T37 page */
+   ret = __mxt_read_reg(data->client, dbg->t37_address,
+   sizeof(struct t37_debug), p);
+   if (ret)
+   return ret;
+
+   if ((p->mode != mode) || (p->page != page)) {
+   dev_err(>client->dev, "T37 page mismatch\n");
+   return -EINVAL;
+   }
+
+   dev_dbg(>client->dev, "%s page:%d retries:%d\n",
+   __func__, page, retries);
+
+   /* For remaining pages, write PAGEUP rather than mode */
+   cmd = MXT_DIAGNOSTIC_PAGEUP;
+   }
+
+   return mxt_convert_debug_pages(data, outbuf);
+}
+
+static void mxt_debug_init(struct mxt_data *data)
+{
+   struct mxt_dbg *dbg = >dbg;
+   struct mxt_object *object;
+
+   object = mxt_get_object(data, MXT_GEN_COMMAND_T6);
+   if (!object)
+   return;
+
+   dbg->diag_cmd_address = object->start_address + MXT_COMMAND_DIAGNOSTIC;
+
+   object = mxt_get_object(data, MXT_DEBUG_DIAGNOSTIC_T3

[PATCH v3 7/8] Input: atmel_mxt_ts - add diagnostic data support for mXT1386

2016-06-01 Thread Nick Dyer
The mXT1386 family of chips have a different architecture which splits
the diagnostic data into 3 columns.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 29 ++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index eced661..7d8002d 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -137,6 +137,10 @@ struct t9_range {
 #define MXT_DIAGNOSTIC_DELTAS  0x10
 #define MXT_DIAGNOSTIC_SIZE128
 
+#define MXT_FAMILY_1386160
+#define MXT1386_COLUMNS3
+#define MXT1386_PAGES_PER_COLUMN   8
+
 struct t37_debug {
u8 mode;
u8 page;
@@ -2135,13 +2139,27 @@ recheck:
 static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
   unsigned int y)
 {
+   struct mxt_info *info = >info;
struct mxt_dbg *dbg = >dbg;
unsigned int ofs, page;
+   unsigned int col = 0;
+   unsigned int col_width;
+
+   if (info->family_id == MXT_FAMILY_1386) {
+   col_width = info->matrix_ysize / MXT1386_COLUMNS;
+   col = y / col_width;
+   y = y % col_width;
+   } else {
+   col_width = info->matrix_ysize;
+   }
 
-   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   ofs = (y + (x * col_width)) * sizeof(u16);
page = ofs / MXT_DIAGNOSTIC_SIZE;
ofs %= MXT_DIAGNOSTIC_SIZE;
 
+   if (info->family_id == MXT_FAMILY_1386)
+   page += col * MXT1386_PAGES_PER_COLUMN;
+
return get_unaligned_le16(>t37_buf[page].data[ofs]);
 }
 
@@ -2411,6 +2429,7 @@ static const struct video_device mxt_video_device = {
 
 static void mxt_debug_init(struct mxt_data *data)
 {
+   struct mxt_info *info = >info;
struct mxt_dbg *dbg = >dbg;
struct mxt_object *object;
int error;
@@ -2434,9 +2453,13 @@ static void mxt_debug_init(struct mxt_data *data)
 
/* Calculate size of data and allocate buffer */
dbg->t37_nodes = data->xsize * data->ysize;
-   dbg->t37_pages = ((data->xsize * data->info.matrix_ysize)
- * sizeof(u16) / sizeof(dbg->t37_buf->data)) + 1;
 
+   if (info->family_id == MXT_FAMILY_1386)
+   dbg->t37_pages = MXT1386_COLUMNS * MXT1386_PAGES_PER_COLUMN;
+   else
+   dbg->t37_pages = ((data->xsize * info->matrix_ysize)
+  * sizeof(u16) / sizeof(dbg->t37_buf->data))
+  + 1;
 
dbg->t37_buf = devm_kzalloc(>client->dev,
 sizeof(struct t37_debug) * dbg->t37_pages,
-- 
2.5.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


[PATCH v3 8/8] Input: atmel_mxt_ts - add support for reference data

2016-06-01 Thread Nick Dyer
There are different datatypes available from a maXTouch chip. Add
support to retrieve reference data as well.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 58 
 1 file changed, 51 insertions(+), 7 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 7d8002d..d9e0906 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -135,6 +135,7 @@ struct t9_range {
 /* MXT_DEBUG_DIAGNOSTIC_T37 */
 #define MXT_DIAGNOSTIC_PAGEUP  0x01
 #define MXT_DIAGNOSTIC_DELTAS  0x10
+#define MXT_DIAGNOSTIC_REFS0x11
 #define MXT_DIAGNOSTIC_SIZE128
 
 #define MXT_FAMILY_1386160
@@ -247,6 +248,12 @@ struct mxt_dbg {
int input;
 };
 
+enum v4l_dbg_inputs {
+   MXT_V4L_INPUT_DELTAS,
+   MXT_V4L_INPUT_REFS,
+   MXT_V4L_INPUT_MAX,
+};
+
 static const struct v4l2_file_operations mxt_video_fops = {
.owner = THIS_MODULE,
.open = v4l2_fh_open,
@@ -2268,6 +2275,7 @@ static void mxt_buffer_queue(struct vb2_buffer *vb)
struct mxt_data *data = vb2_get_drv_priv(vb->vb2_queue);
u16 *ptr;
int ret;
+   u8 mode;
 
ptr = vb2_plane_vaddr(vb, 0);
if (!ptr) {
@@ -2275,7 +2283,18 @@ static void mxt_buffer_queue(struct vb2_buffer *vb)
goto fault;
}
 
-   ret = mxt_read_diagnostic_debug(data, MXT_DIAGNOSTIC_DELTAS, ptr);
+   switch (data->dbg.input) {
+   case MXT_V4L_INPUT_DELTAS:
+   default:
+   mode = MXT_DIAGNOSTIC_DELTAS;
+   break;
+
+   case MXT_V4L_INPUT_REFS:
+   mode = MXT_DIAGNOSTIC_REFS;
+   break;
+   }
+
+   ret = mxt_read_diagnostic_debug(data, mode, ptr);
if (ret)
goto fault;
 
@@ -2320,11 +2339,20 @@ static int mxt_vidioc_querycap(struct file *file, void 
*priv,
 static int mxt_vidioc_enum_input(struct file *file, void *priv,
   struct v4l2_input *i)
 {
-   if (i->index > 0)
+   if (i->index >= MXT_V4L_INPUT_MAX)
return -EINVAL;
 
i->type = V4L2_INPUT_TYPE_TOUCH_SENSOR;
-   strlcpy(i->name, "Mutual References", sizeof(i->name));
+
+   switch (i->index) {
+   case MXT_V4L_INPUT_REFS:
+   strlcpy(i->name, "Mutual References", sizeof(i->name));
+   break;
+   case MXT_V4L_INPUT_DELTAS:
+   strlcpy(i->name, "Mutual Deltas", sizeof(i->name));
+   break;
+   }
+
return 0;
 }
 
@@ -2332,12 +2360,16 @@ static int mxt_set_input(struct mxt_data *data, 
unsigned int i)
 {
struct v4l2_pix_format *f = >dbg.format;
 
-   if (i > 0)
+   if (i >= MXT_V4L_INPUT_MAX)
return -EINVAL;
 
+   if (i == MXT_V4L_INPUT_DELTAS)
+   f->pixelformat = V4L2_PIX_FMT_YS16;
+   else
+   f->pixelformat = V4L2_PIX_FMT_Y16;
+
f->width = data->xy_switch ? data->ysize : data->xsize;
f->height = data->xy_switch ? data->xsize : data->ysize;
-   f->pixelformat = V4L2_PIX_FMT_YS16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
f->bytesperline = f->width * sizeof(u16);
@@ -2375,10 +2407,22 @@ static int mxt_vidioc_fmt(struct file *file, void 
*priv, struct v4l2_format *f)
 static int mxt_vidioc_enum_fmt(struct file *file, void *priv,
 struct v4l2_fmtdesc *fmt)
 {
-   if (fmt->index > 0 || fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   return -EINVAL;
+
+   switch (fmt->index) {
+   case 0:
+   fmt->pixelformat = V4L2_PIX_FMT_Y16;
+   break;
+
+   case 1:
+   fmt->pixelformat = V4L2_PIX_FMT_YS16;
+   break;
+
+   default:
return -EINVAL;
+   }
 
-   fmt->pixelformat = V4L2_PIX_FMT_YS16;
return 0;
 }
 
-- 
2.5.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


[PATCH v3 5/8] Input: atmel_mxt_ts - read touchscreen size

2016-06-01 Thread Nick Dyer
The touchscreen may have a margin where not all the matrix is used. Read
the parameters from T9 and T100 and take account of the difference.

Note: this does not read the XORIGIN/YORIGIN fields so it assumes that
the touchscreen starts at (0,0)

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 43 +++-
 1 file changed, 37 insertions(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 8608cb1..ac4126c 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -103,6 +103,8 @@ struct t7_config {
 
 /* MXT_TOUCH_MULTI_T9 field */
 #define MXT_T9_CTRL0
+#define MXT_T9_XSIZE   3
+#define MXT_T9_YSIZE   4
 #define MXT_T9_ORIENT  9
 #define MXT_T9_RANGE   18
 
@@ -148,7 +150,9 @@ struct t37_debug {
 #define MXT_T100_CTRL  0
 #define MXT_T100_CFG1  1
 #define MXT_T100_TCHAUX3
+#define MXT_T100_XSIZE 9
 #define MXT_T100_XRANGE13
+#define MXT_T100_YSIZE 20
 #define MXT_T100_YRANGE24
 
 #define MXT_T100_CFG_SWITCHXY  BIT(5)
@@ -257,6 +261,8 @@ struct mxt_data {
unsigned int max_x;
unsigned int max_y;
bool xy_switch;
+   u8 xsize;
+   u8 ysize;
bool in_bootloader;
u16 mem_size;
u8 t100_aux_ampl;
@@ -1710,6 +1716,18 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return -EINVAL;
 
error = __mxt_read_reg(client,
+  object->start_address + MXT_T9_XSIZE,
+  sizeof(data->xsize), >xsize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T9_YSIZE,
+  sizeof(data->ysize), >ysize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
   object->start_address + MXT_T9_RANGE,
   sizeof(range), );
if (error)
@@ -1759,6 +1777,18 @@ static int mxt_read_t100_config(struct mxt_data *data)
 
data->max_y = get_unaligned_le16(_y);
 
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T100_XSIZE,
+  sizeof(data->xsize), >xsize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T100_YSIZE,
+  sizeof(data->ysize), >ysize);
+   if (error)
+   return error;
+
/* read orientation config */
error =  __mxt_read_reg(client,
object->start_address + MXT_T100_CFG1,
@@ -2116,7 +2146,7 @@ static int mxt_convert_debug_pages(struct mxt_data *data, 
u16 *outbuf)
outbuf[i] = mxt_get_debug_value(data, x, y);
 
/* Next value */
-   if (++x >= data->info.matrix_xsize) {
+   if (++x >= data->xsize) {
x = 0;
y++;
}
@@ -2271,8 +2301,8 @@ static int mxt_set_input(struct mxt_data *data, unsigned 
int i)
if (i > 0)
return -EINVAL;
 
-   f->width = data->info.matrix_xsize;
-   f->height = data->info.matrix_ysize;
+   f->width = data->xsize;
+   f->height = data->ysize;
f->pixelformat = V4L2_PIX_FMT_YS16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_RAW;
@@ -2387,9 +2417,10 @@ static void mxt_debug_init(struct mxt_data *data)
dbg->t37_address = object->start_address;
 
/* Calculate size of data and allocate buffer */
-   dbg->t37_nodes = data->info.matrix_xsize * data->info.matrix_ysize;
-   dbg->t37_pages = dbg->t37_nodes * sizeof(u16)
-   / sizeof(dbg->t37_buf->data) + 1;
+   dbg->t37_nodes = data->xsize * data->ysize;
+   dbg->t37_pages = ((data->xsize * data->info.matrix_ysize)
+ * sizeof(u16) / sizeof(dbg->t37_buf->data)) + 1;
+
 
dbg->t37_buf = devm_kzalloc(>client->dev,
 sizeof(struct t37_debug) * dbg->t37_pages,
-- 
2.5.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


Re: [PATCH v2 4/8] Input: atmel_mxt_ts - output diagnostic debug via v4l2 device

2016-06-01 Thread Nick Dyer
On 27/05/2016 13:54, Hans Verkuil wrote:
> Hi Nick,

Thanks for the useful review. Most of it is straightforward and I've
updated it in a new version of these patches which I will post now.

I think the open question is whether you're happy with the
V4L2_PIX_FMT_YS16 or whether I need to rename it. For what it's worth,
Synaptics RMI4 also emits 16 bit signed, see

https://github.com/wanam/Adam-Kernel-GS4/blob/master/drivers/input/touchscreen/rmi_f54.c#L1831

> On 05/04/2016 07:07 PM, Nick Dyer wrote:
> BTW, did you run v4l2-compliance? I think it should work if you just do:
> 
> v4l2-compliance -d /dev/v4l-touch0

Yes, and I've now fixed all issues that I could find with it. I had to do
some minor updates to support the touch sensor stuff, see:
https://github.com/ndyer/v4l-utils/commits/touch-sensor
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/8] [media] Add signed 16-bit pixel format

2016-05-27 Thread Nick Dyer
On 27/05/2016 14:18, Hans Verkuil wrote:
> On 05/27/2016 02:52 PM, Nick Dyer wrote:
>> On 27/05/2016 13:38, Hans Verkuil wrote:
>>> On 05/04/2016 07:07 PM, Nick Dyer wrote:
>>>> +V4L2_PIX_FMT_YS16
>>>> +Grey-scale image
>>>> +  
>>>> +  
>>>> +Description
>>>> +
>>>> +This is a signed grey-scale image with a depth of 16 bits per
>>>> +pixel. The most significant byte is stored at higher memory addresses
>>>> +(little-endian).
>>>
>>> I'm not sure this should be described in terms of grey-scale, since negative
>>> values make no sense for that. How are these values supposed to be 
>>> interpreted
>>> if you want to display them? -32768 == black and 32767 is white?
>>
>> We have written a utility to display this data and it is able to display
>> the values mapped to grayscale or color:
>> https://github.com/ndyer/heatmap/blob/master/src/display.c#L44
>>
>> An example of the output is here:
>> https://www.youtube.com/watch?v=Uj4T6fUCySw
>>
>> The data is intrinsically signed because that's how the low level touch
>> controller treats it. I'm happy to change it to "Signed image" if you think
>> that would be better.
> 
> A V4L2_PIX_FMT_ definition must specify the format unambiguously. So it is not
> enough to just say that the data is a signed 16 bit value, you need to 
> document
> exactly how it should be interpreted. Looking at the code it seems that the
> signed values are within a certain range and are normalized to 0-max by this 
> line:
> 
> ssize_t gray = (data[i] - cfg->min) * max / (cfg->max - cfg->min);
> 
> Are the min/max values defined by the hardware? Because in that case this 
> pixel
> format has to be a hardware-specific define (e.g. V4L2_PIX_FMT_FOO_S16).
> 
> Only if the min/max values are -32768 and 32767 can you really use YS16 (not 
> sure
> yet about that name, but that's another issue).

I'm sorry, perhaps that is slightly misleading.

The data being output is the raw capacitance values from the analogue
front-end in the touch controller. Due to the physical characteristics,
there is a small range in the middle of the possible outputs of the ADC
which is interesting, and the heatmap tool allows mapping just that range
to the possible colors, otherwise everything would look mid-grey. So
heatmap is doing a job conceptually like adjusting the black point and
white point of a greyscale image to bring out the detail.

So the hardware itself doesn't have a conception of what those min/max
values are - from the hardware point of view the values may range from
-32768 to 32767 (in fact such values are commonly seen when one of the
touchscreen lines has a fault or is not connected).
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/8] [media] Add signed 16-bit pixel format

2016-05-27 Thread Nick Dyer
On 27/05/2016 13:38, Hans Verkuil wrote:
> On 05/04/2016 07:07 PM, Nick Dyer wrote:
>> +V4L2_PIX_FMT_YS16
>> +Grey-scale image
>> +  
>> +  
>> +Description
>> +
>> +This is a signed grey-scale image with a depth of 16 bits per
>> +pixel. The most significant byte is stored at higher memory addresses
>> +(little-endian).
> 
> I'm not sure this should be described in terms of grey-scale, since negative
> values make no sense for that. How are these values supposed to be interpreted
> if you want to display them? -32768 == black and 32767 is white?

We have written a utility to display this data and it is able to display
the values mapped to grayscale or color:
https://github.com/ndyer/heatmap/blob/master/src/display.c#L44

An example of the output is here:
https://www.youtube.com/watch?v=Uj4T6fUCySw

The data is intrinsically signed because that's how the low level touch
controller treats it. I'm happy to change it to "Signed image" if you think
that would be better.
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 0/8] Input: atmel_mxt_ts - output raw touch diagnostic data via V4L

2016-05-13 Thread Nick Dyer
Hi Mauro, Hans, Dmitry, Henrik-

You kindly passed comment on this feature in its earlier form - would it be
possible to have some feedback on the updates?

It would be good to know whether we are on the right track with the V4L2
approach, because there is additional work that we want to base on it.

best regards

Nick

On 04/05/2016 18:07, Nick Dyer wrote:
> This is a series of patches to add diagnostic data support to the Atmel
> maXTouch driver. It's a rewrite of the previous implementation which output 
> via
> debugfs: it now uses a V4L2 device in a similar way to the sur40 driver.
> 
> There are significant performance advantages to putting this code into the
> driver.  The algorithm for retrieving the data has been fairly consistent
> across a range of chips, with the exception of the mXT1386 series (see patch).
> 
> We have a utility which can read the data and display it in a useful format:
> https://github.com/ndyer/heatmap/commits/heatmap-v4l
> 
> These patches are also available from
> https://github.com/ndyer/linux/commits/diagnostic-v4l
> 
> Changes in v2:
> - Split pixfmt changes into separate commit and add DocBook
> - Introduce VFL_TYPE_TOUCH_SENSOR and /dev/v4l-touch
> - Remove "single node" support for now, it may be better to treat it as 
> metadata later
> - Explicitly set VFL_DIR_RX
> - Fix Kconfig
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" 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


[PATCH v2 1/8] Input: atmel_mxt_ts - add support for T37 diagnostic data

2016-05-04 Thread Nick Dyer
Atmel maXTouch devices have a T37 object which can be used to read raw
touch deltas from the device. This consists of an array of 16-bit
integers, one for each node on the touchscreen matrix.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 152 +++
 1 file changed, 152 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2160512..cd97713 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -124,6 +124,17 @@ struct t9_range {
 #define MXT_COMMS_CTRL 0
 #define MXT_COMMS_CMD  1
 
+/* MXT_DEBUG_DIAGNOSTIC_T37 */
+#define MXT_DIAGNOSTIC_PAGEUP  0x01
+#define MXT_DIAGNOSTIC_DELTAS  0x10
+#define MXT_DIAGNOSTIC_SIZE128
+
+struct t37_debug {
+   u8 mode;
+   u8 page;
+   u8 data[MXT_DIAGNOSTIC_SIZE];
+};
+
 /* Define for MXT_GEN_COMMAND_T6 */
 #define MXT_BOOT_VALUE 0xa5
 #define MXT_RESET_VALUE0x01
@@ -205,6 +216,14 @@ struct mxt_object {
u8 num_report_ids;
 } __packed;
 
+struct mxt_dbg {
+   u16 t37_address;
+   u16 diag_cmd_address;
+   struct t37_debug *t37_buf;
+   unsigned int t37_pages;
+   unsigned int t37_nodes;
+};
+
 /* Each client has this additional data */
 struct mxt_data {
struct i2c_client *client;
@@ -233,6 +252,7 @@ struct mxt_data {
u8 num_touchids;
u8 multitouch;
struct t7_config t7_cfg;
+   struct mxt_dbg dbg;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -2043,6 +2063,136 @@ recheck:
return 0;
 }
 
+static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
+  unsigned int y)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int ofs, page;
+
+   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   page = ofs / MXT_DIAGNOSTIC_SIZE;
+   ofs %= MXT_DIAGNOSTIC_SIZE;
+
+   return get_unaligned_le16(>t37_buf[page].data[ofs]);
+}
+
+static int mxt_convert_debug_pages(struct mxt_data *data, u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int x = 0;
+   unsigned int y = 0;
+   unsigned int i;
+
+   for (i = 0; i < dbg->t37_nodes; i++) {
+   outbuf[i] = mxt_get_debug_value(data, x, y);
+
+   /* Next value */
+   if (++x >= data->info.matrix_xsize) {
+   x = 0;
+   y++;
+   }
+   }
+
+   return 0;
+}
+
+static int mxt_read_diagnostic_debug(struct mxt_data *data, u8 mode,
+u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   int retries = 0;
+   int page;
+   int ret;
+   u8 cmd = mode;
+   struct t37_debug *p;
+   u8 cmd_poll;
+
+   for (page = 0; page < dbg->t37_pages; page++) {
+   p = dbg->t37_buf + page;
+
+   ret = mxt_write_reg(data->client, dbg->diag_cmd_address,
+   cmd);
+   if (ret)
+   return ret;
+
+   retries = 0;
+   msleep(20);
+wait_cmd:
+   /* Read back command byte */
+   ret = __mxt_read_reg(data->client, dbg->diag_cmd_address,
+sizeof(cmd_poll), _poll);
+   if (ret)
+   return ret;
+
+   /* Field is cleared once the command has been processed */
+   if (cmd_poll) {
+   if (retries++ > 100)
+   return -EINVAL;
+
+   msleep(20);
+   goto wait_cmd;
+   }
+
+   /* Read T37 page */
+   ret = __mxt_read_reg(data->client, dbg->t37_address,
+   sizeof(struct t37_debug), p);
+   if (ret)
+   return ret;
+
+   if ((p->mode != mode) || (p->page != page)) {
+   dev_err(>client->dev, "T37 page mismatch\n");
+   return -EINVAL;
+   }
+
+   dev_dbg(>client->dev, "%s page:%d retries:%d\n",
+   __func__, page, retries);
+
+   /* For remaining pages, write PAGEUP rather than mode */
+   cmd = MXT_DIAGNOSTIC_PAGEUP;
+   }
+
+   return mxt_convert_debug_pages(data, outbuf);
+}
+
+static void mxt_debug_init(struct mxt_data *data)
+{
+   struct mxt_dbg *dbg = >dbg;
+   struct mxt_object *object;
+
+   object = mxt_get_object(data, MXT_GEN_COMMAND_T6);
+   if (!object)
+   return;
+
+   dbg->diag_cmd_address = object->start_address + MXT_COMMAND_DIAGNOSTIC;
+
+   object = mxt_get_object(data, MXT_DEBUG_DIAGNOSTIC_T3

[PATCH v2 3/8] [media] v4l2-core: Add VFL_TYPE_TOUCH_SENSOR

2016-05-04 Thread Nick Dyer
Some touch controllers send out raw touch data in a similar way to a
greyscale frame grabber. Add a new device type for these devices.

Use a new device prefix v4l-touch for these devices, to stop generic
capture software from treating them as webcams.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/sur40.c|  2 +-
 drivers/media/v4l2-core/v4l2-dev.c   | 13 ++---
 drivers/media/v4l2-core/v4l2-ioctl.c |  6 --
 include/media/v4l2-dev.h |  3 ++-
 4 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/input/touchscreen/sur40.c 
b/drivers/input/touchscreen/sur40.c
index 880c40b..7e5fe2b 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -599,7 +599,7 @@ static int sur40_probe(struct usb_interface *interface,
sur40->vdev.queue = >queue;
video_set_drvdata(>vdev, sur40);
 
-   error = video_register_device(>vdev, VFL_TYPE_GRABBER, -1);
+   error = video_register_device(>vdev, VFL_TYPE_TOUCH_SENSOR, -1);
if (error) {
dev_err(>dev,
"Unable to register video subdevice.");
diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index d8e5994..8d41248 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -529,6 +529,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR;
bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
+   bool is_touch = vdev->vfl_type == VFL_TYPE_TOUCH_SENSOR;
 
bitmap_zero(valid_ioctls, BASE_VIDIOC_PRIVATE);
 
@@ -573,7 +574,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
if (ops->vidioc_enum_freq_bands || ops->vidioc_g_tuner || 
ops->vidioc_g_modulator)
set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls);
 
-   if (is_vid) {
+   if (is_vid || is_touch) {
/* video specific ioctls */
if ((is_rx && (ops->vidioc_enum_fmt_vid_cap ||
   ops->vidioc_enum_fmt_vid_cap_mplane ||
@@ -662,7 +663,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
}
 
-   if (is_vid || is_vbi || is_sdr) {
+   if (is_vid || is_vbi || is_sdr || is_touch) {
/* ioctls valid for video, vbi or sdr */
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
@@ -675,7 +676,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
}
 
-   if (is_vid || is_vbi) {
+   if (is_vid || is_vbi || is_touch) {
/* ioctls valid for video or vbi */
if (ops->vidioc_s_std)
set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
@@ -738,6 +739,7 @@ static int video_register_media_controller(struct 
video_device *vdev, int type)
vdev->entity.function = MEDIA_ENT_F_UNKNOWN;
 
switch (type) {
+   case VFL_TYPE_TOUCH_SENSOR:
case VFL_TYPE_GRABBER:
intf_type = MEDIA_INTF_T_V4L_VIDEO;
vdev->entity.function = MEDIA_ENT_F_IO_V4L;
@@ -844,6 +846,8 @@ static int video_register_media_controller(struct 
video_device *vdev, int type)
  * %VFL_TYPE_SUBDEV - A subdevice
  *
  * %VFL_TYPE_SDR - Software Defined Radio
+ *
+ * %VFL_TYPE_TOUCH_SENSOR - A touch sensor
  */
 int __video_register_device(struct video_device *vdev, int type, int nr,
int warn_if_nr_in_use, struct module *owner)
@@ -887,6 +891,9 @@ int __video_register_device(struct video_device *vdev, int 
type, int nr,
/* Use device name 'swradio' because 'sdr' was already taken. */
name_base = "swradio";
break;
+   case VFL_TYPE_TOUCH_SENSOR:
+   name_base = "v4l-touch";
+   break;
default:
printk(KERN_ERR "%s called with unknown type: %d\n",
   __func__, type);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index c7dabaa..4a1093a 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -925,13 +925,14 @@ static int check_fmt(struct file *file, enum 
v4l2_buf_type type)
bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
+   bool is_touch = vfd->vfl_type == VFL_TYPE_TOUCH_SENSOR;
 
if (ops == NULL)
return -EINVAL;
 
switch (type) {

[PATCH v2 8/8] Input: atmel_mxt_ts - add support for reference data

2016-05-04 Thread Nick Dyer
There are different datatypes available from a maXTouch chip. Add
support to retrieve reference data as well.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 66 +++-
 1 file changed, 56 insertions(+), 10 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index fca1096..1d9909f 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -135,6 +135,7 @@ struct t9_range {
 /* MXT_DEBUG_DIAGNOSTIC_T37 */
 #define MXT_DIAGNOSTIC_PAGEUP  0x01
 #define MXT_DIAGNOSTIC_DELTAS  0x10
+#define MXT_DIAGNOSTIC_REFS0x11
 #define MXT_DIAGNOSTIC_SIZE128
 
 #define MXT_FAMILY_1386160
@@ -247,6 +248,12 @@ struct mxt_dbg {
int input;
 };
 
+enum v4l_dbg_inputs {
+   MXT_V4L_INPUT_DELTAS,
+   MXT_V4L_INPUT_REFS,
+   MXT_V4L_INPUT_MAX,
+};
+
 static const struct v4l2_file_operations mxt_video_fops = {
.owner = THIS_MODULE,
.open = v4l2_fh_open,
@@ -2270,6 +2277,7 @@ static void mxt_buffer_queue(struct vb2_buffer *vb)
struct mxt_data *data = vb2_get_drv_priv(vb->vb2_queue);
u16 *ptr;
int ret;
+   u8 mode;
 
ptr = vb2_plane_vaddr(vb, 0);
if (!ptr) {
@@ -2277,7 +2285,18 @@ static void mxt_buffer_queue(struct vb2_buffer *vb)
goto fault;
}
 
-   ret = mxt_read_diagnostic_debug(data, MXT_DIAGNOSTIC_DELTAS, ptr);
+   switch (data->dbg.input) {
+   case MXT_V4L_INPUT_DELTAS:
+   default:
+   mode = MXT_DIAGNOSTIC_DELTAS;
+   break;
+
+   case MXT_V4L_INPUT_REFS:
+   mode = MXT_DIAGNOSTIC_REFS;
+   break;
+   }
+
+   ret = mxt_read_diagnostic_debug(data, mode, ptr);
if (ret)
goto fault;
 
@@ -2327,13 +2346,22 @@ static int mxt_vidioc_querycap(struct file *file, void 
*priv,
 static int mxt_vidioc_enum_input(struct file *file, void *priv,
   struct v4l2_input *i)
 {
-   if (i->index > 0)
+   if (i->index >= MXT_V4L_INPUT_MAX)
return -EINVAL;
 
i->type = V4L2_INPUT_TYPE_CAMERA;
i->std = V4L2_STD_UNKNOWN;
i->capabilities = 0;
-   strlcpy(i->name, "Mutual References", sizeof(i->name));
+
+   switch (i->index) {
+   case MXT_V4L_INPUT_REFS:
+   strlcpy(i->name, "Mutual References", sizeof(i->name));
+   break;
+   case MXT_V4L_INPUT_DELTAS:
+   strlcpy(i->name, "Mutual Deltas", sizeof(i->name));
+   break;
+   }
+
return 0;
 }
 
@@ -2341,12 +2369,16 @@ static int mxt_set_input(struct mxt_data *data, 
unsigned int i)
 {
struct v4l2_pix_format *f = >dbg.format;
 
-   if (i > 0)
+   if (i >= MXT_V4L_INPUT_MAX)
return -EINVAL;
 
+   if (i == MXT_V4L_INPUT_DELTAS)
+   f->pixelformat = V4L2_PIX_FMT_YS16;
+   else
+   f->pixelformat = V4L2_PIX_FMT_Y16;
+
f->width = data->xy_switch ? data->ysize : data->xsize;
f->height = data->xy_switch ? data->xsize : data->ysize;
-   f->pixelformat = V4L2_PIX_FMT_YS16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_SRGB;
f->bytesperline = f->width * sizeof(u16);
@@ -2383,12 +2415,26 @@ static int mxt_vidioc_fmt(struct file *file, void 
*priv, struct v4l2_format *f)
 static int mxt_vidioc_enum_fmt(struct file *file, void *priv,
 struct v4l2_fmtdesc *fmt)
 {
-   if (fmt->index > 0 || fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+   return -EINVAL;
+
+   switch (fmt->index) {
+   case 0:
+   fmt->pixelformat = V4L2_PIX_FMT_Y16;
+   strlcpy(fmt->description, "16-bit unsigned raw debug data",
+   sizeof(fmt->description));
+   break;
+
+   case 1:
+   fmt->pixelformat = V4L2_PIX_FMT_YS16;
+   strlcpy(fmt->description, "16-bit signed raw debug data",
+   sizeof(fmt->description));
+   break;
+
+   default:
return -EINVAL;
+   }
 
-   fmt->pixelformat = V4L2_PIX_FMT_YS16;
-   strlcpy(fmt->description, "16-bit raw debug data",
-   sizeof(fmt->description));
fmt->flags = 0;
return 0;
 }
@@ -2410,7 +2456,7 @@ static int mxt_vidioc_enum_framesizes(struct file *file, 
void *priv,
 static int mxt_vidioc_enum_frameintervals(struct file *file, void *priv,
  struct v4l2_frmivalenum *f)
 {
-   if ((f->in

[PATCH v2 4/8] Input: atmel_mxt_ts - output diagnostic debug via v4l2 device

2016-05-04 Thread Nick Dyer
Register a video device to output T37 diagnostic data.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/Kconfig|   2 +
 drivers/input/touchscreen/atmel_mxt_ts.c | 271 +++
 2 files changed, 273 insertions(+)

diff --git a/drivers/input/touchscreen/Kconfig 
b/drivers/input/touchscreen/Kconfig
index 1f99e7f..4aa7609 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -105,6 +105,8 @@ config TOUCHSCREEN_AR1021_I2C
 config TOUCHSCREEN_ATMEL_MXT
tristate "Atmel mXT I2C Touchscreen"
depends on I2C
+   depends on VIDEO_V4L2
+   select VIDEOBUF2_VMALLOC
select FW_LOADER
help
  Say Y here if you have Atmel mXT series I2C touchscreen,
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index cd97713..8945235 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -28,6 +28,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 /* Firmware files */
 #define MXT_FW_NAME"maxtouch.fw"
@@ -222,6 +226,23 @@ struct mxt_dbg {
struct t37_debug *t37_buf;
unsigned int t37_pages;
unsigned int t37_nodes;
+
+   struct v4l2_device v4l2;
+   struct v4l2_pix_format format;
+   struct video_device vdev;
+   struct vb2_queue queue;
+   struct mutex lock;
+   int input;
+};
+
+static const struct v4l2_file_operations mxt_video_fops = {
+   .owner = THIS_MODULE,
+   .open = v4l2_fh_open,
+   .release = vb2_fop_release,
+   .unlocked_ioctl = video_ioctl2,
+   .read = vb2_fop_read,
+   .mmap = vb2_fop_mmap,
+   .poll = vb2_fop_poll,
 };
 
 /* Each client has this additional data */
@@ -277,6 +298,11 @@ struct mxt_data {
struct completion crc_completion;
 };
 
+struct mxt_vb2_buffer {
+   struct vb2_buffer   vb;
+   struct list_headlist;
+};
+
 static size_t mxt_obj_size(const struct mxt_object *obj)
 {
return obj->size_minus_one + 1;
@@ -1523,6 +1549,9 @@ static void mxt_free_input_device(struct mxt_data *data)
 
 static void mxt_free_object_table(struct mxt_data *data)
 {
+   video_unregister_device(>dbg.vdev);
+   v4l2_device_unregister(>dbg.v4l2);
+
kfree(data->object_table);
data->object_table = NULL;
kfree(data->msg_buf);
@@ -2154,10 +2183,215 @@ wait_cmd:
return mxt_convert_debug_pages(data, outbuf);
 }
 
+static int mxt_queue_setup(struct vb2_queue *q,
+  unsigned int *nbuffers, unsigned int *nplanes,
+  unsigned int sizes[], void *alloc_ctxs[])
+{
+   struct mxt_data *data = q->drv_priv;
+
+   *nbuffers = 1;
+   *nplanes = 1;
+   sizes[0] = data->dbg.t37_nodes * sizeof(u16);
+
+   return 0;
+}
+
+static int mxt_buffer_prepare(struct vb2_buffer *vb)
+{
+   return 0;
+}
+
+static void mxt_buffer_queue(struct vb2_buffer *vb)
+{
+   struct mxt_data *data = vb2_get_drv_priv(vb->vb2_queue);
+   u16 *ptr;
+   int ret;
+
+   ptr = vb2_plane_vaddr(vb, 0);
+   if (!ptr) {
+   dev_err(>client->dev, "Error acquiring frame ptr\n");
+   goto fault;
+   }
+
+   ret = mxt_read_diagnostic_debug(data, MXT_DIAGNOSTIC_DELTAS, ptr);
+   if (ret)
+   goto fault;
+
+   vb2_set_plane_payload(vb, 0, data->dbg.t37_nodes * sizeof(u16));
+   vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+   return;
+
+fault:
+   vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+}
+
+/* V4L2 structures */
+static const struct vb2_ops mxt_queue_ops = {
+   .queue_setup= mxt_queue_setup,
+   .buf_prepare= mxt_buffer_prepare,
+   .buf_queue  = mxt_buffer_queue,
+   .wait_prepare   = vb2_ops_wait_prepare,
+   .wait_finish= vb2_ops_wait_finish,
+};
+
+static const struct vb2_queue mxt_queue = {
+   .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+   .io_modes = VB2_MMAP,
+   .buf_struct_size = sizeof(struct mxt_vb2_buffer),
+   .ops = _queue_ops,
+   .mem_ops = _vmalloc_memops,
+   .timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC,
+   .min_buffers_needed = 1,
+};
+
+static int mxt_vidioc_querycap(struct file *file, void *priv,
+struct v4l2_capability *cap)
+{
+   struct mxt_data *data = video_drvdata(file);
+
+   strlcpy(cap->driver, "atmel_mxt_ts", sizeof(cap->driver));
+   strlcpy(cap->card, "atmel_mxt_ts touch", sizeof(cap->card));
+   strlcpy(cap->bus_info, data->phys, sizeof(cap->bus_info));
+   cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
+   V4L2_CAP_READWRITE |
+   V4L2_CAP_STREAMING;
+   cap->capabilities = cap-

[PATCH v2 6/8] Input: atmel_mxt_ts - handle diagnostic data orientation

2016-05-04 Thread Nick Dyer
Invert the diagnostic data to match the orientation of the input device.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 30 +++---
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index dbe0f2f..b4abd78 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -125,6 +125,8 @@ struct t9_range {
 
 /* MXT_TOUCH_MULTI_T9 orient */
 #define MXT_T9_ORIENT_SWITCH   (1 << 0)
+#define MXT_T9_ORIENT_INVERTX  (1 << 1)
+#define MXT_T9_ORIENT_INVERTY  (1 << 2)
 
 /* MXT_SPT_COMMSCONFIG_T18 */
 #define MXT_COMMS_CTRL 0
@@ -156,6 +158,8 @@ struct t37_debug {
 #define MXT_T100_YRANGE24
 
 #define MXT_T100_CFG_SWITCHXY  BIT(5)
+#define MXT_T100_CFG_INVERTY   BIT(6)
+#define MXT_T100_CFG_INVERTX   BIT(7)
 
 #define MXT_T100_TCHAUX_VECT   BIT(0)
 #define MXT_T100_TCHAUX_AMPL   BIT(1)
@@ -260,6 +264,8 @@ struct mxt_data {
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
+   bool invertx;
+   bool inverty;
bool xy_switch;
u8 xsize;
u8 ysize;
@@ -1743,6 +1749,8 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return error;
 
data->xy_switch = orient & MXT_T9_ORIENT_SWITCH;
+   data->invertx = orient & MXT_T9_ORIENT_INVERTX;
+   data->inverty = orient & MXT_T9_ORIENT_INVERTY;
 
return 0;
 }
@@ -1797,6 +1805,8 @@ static int mxt_read_t100_config(struct mxt_data *data)
return error;
 
data->xy_switch = cfg & MXT_T100_CFG_SWITCHXY;
+   data->invertx = cfg & MXT_T100_CFG_INVERTX;
+   data->inverty = cfg & MXT_T100_CFG_INVERTY;
 
/* allocate aux bytes */
error =  __mxt_read_reg(client,
@@ -2140,13 +2150,19 @@ static int mxt_convert_debug_pages(struct mxt_data 
*data, u16 *outbuf)
struct mxt_dbg *dbg = >dbg;
unsigned int x = 0;
unsigned int y = 0;
-   unsigned int i;
+   unsigned int i, rx, ry;
 
for (i = 0; i < dbg->t37_nodes; i++) {
-   outbuf[i] = mxt_get_debug_value(data, x, y);
+   /* Handle orientation */
+   rx = data->xy_switch ? y : x;
+   ry = data->xy_switch ? x : y;
+   rx = data->invertx ? (data->xsize - 1 - rx) : rx;
+   ry = data->inverty ? (data->ysize - 1 - ry) : ry;
+
+   outbuf[i] = mxt_get_debug_value(data, rx, ry);
 
/* Next value */
-   if (++x >= data->xsize) {
+   if (++x >= (data->xy_switch ? data->ysize : data->xsize)) {
x = 0;
y++;
}
@@ -2310,8 +2326,8 @@ static int mxt_set_input(struct mxt_data *data, unsigned 
int i)
if (i > 0)
return -EINVAL;
 
-   f->width = data->xsize;
-   f->height = data->ysize;
+   f->width = data->xy_switch ? data->ysize : data->xsize;
+   f->height = data->xy_switch ? data->xsize : data->ysize;
f->pixelformat = V4L2_PIX_FMT_YS16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_SRGB;
@@ -2367,8 +2383,8 @@ static int mxt_vidioc_enum_framesizes(struct file *file, 
void *priv,
if (f->index > 0)
return -EINVAL;
 
-   f->discrete.width = data->xsize;
-   f->discrete.height = data->ysize;
+   f->discrete.width = data->xy_switch ? data->ysize : data->xsize;
+   f->discrete.height = data->xy_switch ? data->xsize : data->ysize;
f->type = V4L2_FRMSIZE_TYPE_DISCRETE;
return 0;
 }
-- 
2.5.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


[PATCH v2 0/8] Input: atmel_mxt_ts - output raw touch diagnostic data via V4L

2016-05-04 Thread Nick Dyer
This is a series of patches to add diagnostic data support to the Atmel
maXTouch driver. It's a rewrite of the previous implementation which output via
debugfs: it now uses a V4L2 device in a similar way to the sur40 driver.

There are significant performance advantages to putting this code into the
driver.  The algorithm for retrieving the data has been fairly consistent
across a range of chips, with the exception of the mXT1386 series (see patch).

We have a utility which can read the data and display it in a useful format:
https://github.com/ndyer/heatmap/commits/heatmap-v4l

These patches are also available from
https://github.com/ndyer/linux/commits/diagnostic-v4l

Changes in v2:
- Split pixfmt changes into separate commit and add DocBook
- Introduce VFL_TYPE_TOUCH_SENSOR and /dev/v4l-touch
- Remove "single node" support for now, it may be better to treat it as 
metadata later
- Explicitly set VFL_DIR_RX
- Fix Kconfig

--
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 v2 5/8] Input: atmel_mxt_ts - read touchscreen size

2016-05-04 Thread Nick Dyer
The touchscreen may have a margin where not all the matrix is used. Read
the parameters from T9 and T100 and take account of the difference.

Note: this does not read the XORIGIN/YORIGIN fields so it assumes that
the touchscreen starts at (0,0)

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 47 ++--
 1 file changed, 39 insertions(+), 8 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 8945235..dbe0f2f 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -103,6 +103,8 @@ struct t7_config {
 
 /* MXT_TOUCH_MULTI_T9 field */
 #define MXT_T9_CTRL0
+#define MXT_T9_XSIZE   3
+#define MXT_T9_YSIZE   4
 #define MXT_T9_ORIENT  9
 #define MXT_T9_RANGE   18
 
@@ -148,7 +150,9 @@ struct t37_debug {
 #define MXT_T100_CTRL  0
 #define MXT_T100_CFG1  1
 #define MXT_T100_TCHAUX3
+#define MXT_T100_XSIZE 9
 #define MXT_T100_XRANGE13
+#define MXT_T100_YSIZE 20
 #define MXT_T100_YRANGE24
 
 #define MXT_T100_CFG_SWITCHXY  BIT(5)
@@ -257,6 +261,8 @@ struct mxt_data {
unsigned int max_x;
unsigned int max_y;
bool xy_switch;
+   u8 xsize;
+   u8 ysize;
bool in_bootloader;
u16 mem_size;
u8 t100_aux_ampl;
@@ -1710,6 +1716,18 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
return -EINVAL;
 
error = __mxt_read_reg(client,
+  object->start_address + MXT_T9_XSIZE,
+  sizeof(data->xsize), >xsize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T9_YSIZE,
+  sizeof(data->ysize), >ysize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
   object->start_address + MXT_T9_RANGE,
   sizeof(range), );
if (error)
@@ -1759,6 +1777,18 @@ static int mxt_read_t100_config(struct mxt_data *data)
 
data->max_y = get_unaligned_le16(_y);
 
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T100_XSIZE,
+  sizeof(data->xsize), >xsize);
+   if (error)
+   return error;
+
+   error = __mxt_read_reg(client,
+  object->start_address + MXT_T100_YSIZE,
+  sizeof(data->ysize), >ysize);
+   if (error)
+   return error;
+
/* read orientation config */
error =  __mxt_read_reg(client,
object->start_address + MXT_T100_CFG1,
@@ -2116,7 +2146,7 @@ static int mxt_convert_debug_pages(struct mxt_data *data, 
u16 *outbuf)
outbuf[i] = mxt_get_debug_value(data, x, y);
 
/* Next value */
-   if (++x >= data->info.matrix_xsize) {
+   if (++x >= data->xsize) {
x = 0;
y++;
}
@@ -2280,8 +2310,8 @@ static int mxt_set_input(struct mxt_data *data, unsigned 
int i)
if (i > 0)
return -EINVAL;
 
-   f->width = data->info.matrix_xsize;
-   f->height = data->info.matrix_ysize;
+   f->width = data->xsize;
+   f->height = data->ysize;
f->pixelformat = V4L2_PIX_FMT_YS16;
f->field = V4L2_FIELD_NONE;
f->colorspace = V4L2_COLORSPACE_SRGB;
@@ -2337,8 +2367,8 @@ static int mxt_vidioc_enum_framesizes(struct file *file, 
void *priv,
if (f->index > 0)
return -EINVAL;
 
-   f->discrete.width = data->info.matrix_xsize;
-   f->discrete.height = data->info.matrix_ysize;
+   f->discrete.width = data->xsize;
+   f->discrete.height = data->ysize;
f->type = V4L2_FRMSIZE_TYPE_DISCRETE;
return 0;
 }
@@ -2411,9 +2441,10 @@ static void mxt_debug_init(struct mxt_data *data)
dbg->t37_address = object->start_address;
 
/* Calculate size of data and allocate buffer */
-   dbg->t37_nodes = data->info.matrix_xsize * data->info.matrix_ysize;
-   dbg->t37_pages = dbg->t37_nodes * sizeof(u16)
-   / sizeof(dbg->t37_buf->data) + 1;
+   dbg->t37_nodes = data->xsize * data->ysize;
+   dbg->t37_pages = ((data->xsize * data->info.matrix_ysize)
+ * sizeof(u16) / sizeof(dbg->t37_buf->data)) + 1;
+
 
dbg->t37_buf = devm_kzalloc(>client->dev,
 sizeof(struct t37_

[PATCH v2 7/8] Input: atmel_mxt_ts - add diagnostic data support for mXT1386

2016-05-04 Thread Nick Dyer
The mXT1386 family of chips have a different architecture which splits
the diagnostic data into 3 columns.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 29 ++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index b4abd78..fca1096 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -137,6 +137,10 @@ struct t9_range {
 #define MXT_DIAGNOSTIC_DELTAS  0x10
 #define MXT_DIAGNOSTIC_SIZE128
 
+#define MXT_FAMILY_1386160
+#define MXT1386_COLUMNS3
+#define MXT1386_PAGES_PER_COLUMN   8
+
 struct t37_debug {
u8 mode;
u8 page;
@@ -2135,13 +2139,27 @@ recheck:
 static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
   unsigned int y)
 {
+   struct mxt_info *info = >info;
struct mxt_dbg *dbg = >dbg;
unsigned int ofs, page;
+   unsigned int col = 0;
+   unsigned int col_width;
+
+   if (info->family_id == MXT_FAMILY_1386) {
+   col_width = info->matrix_ysize / MXT1386_COLUMNS;
+   col = y / col_width;
+   y = y % col_width;
+   } else {
+   col_width = info->matrix_ysize;
+   }
 
-   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   ofs = (y + (x * col_width)) * sizeof(u16);
page = ofs / MXT_DIAGNOSTIC_SIZE;
ofs %= MXT_DIAGNOSTIC_SIZE;
 
+   if (info->family_id == MXT_FAMILY_1386)
+   page += col * MXT1386_PAGES_PER_COLUMN;
+
return get_unaligned_le16(>t37_buf[page].data[ofs]);
 }
 
@@ -2435,6 +2453,7 @@ static const struct video_device mxt_video_device = {
 
 static void mxt_debug_init(struct mxt_data *data)
 {
+   struct mxt_info *info = >info;
struct mxt_dbg *dbg = >dbg;
struct mxt_object *object;
int error;
@@ -2458,9 +2477,13 @@ static void mxt_debug_init(struct mxt_data *data)
 
/* Calculate size of data and allocate buffer */
dbg->t37_nodes = data->xsize * data->ysize;
-   dbg->t37_pages = ((data->xsize * data->info.matrix_ysize)
- * sizeof(u16) / sizeof(dbg->t37_buf->data)) + 1;
 
+   if (info->family_id == MXT_FAMILY_1386)
+   dbg->t37_pages = MXT1386_COLUMNS * MXT1386_PAGES_PER_COLUMN;
+   else
+   dbg->t37_pages = ((data->xsize * info->matrix_ysize)
+  * sizeof(u16) / sizeof(dbg->t37_buf->data))
+  + 1;
 
dbg->t37_buf = devm_kzalloc(>client->dev,
 sizeof(struct t37_debug) * dbg->t37_pages,
-- 
2.5.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


[PATCH v2 2/8] [media] Add signed 16-bit pixel format

2016-05-04 Thread Nick Dyer
This will be used for output of raw touch data.

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 Documentation/DocBook/media/v4l/pixfmt-ys16.xml | 79 +
 Documentation/DocBook/media/v4l/pixfmt.xml  |  1 +
 drivers/media/v4l2-core/v4l2-ioctl.c|  1 +
 include/uapi/linux/videodev2.h  |  1 +
 4 files changed, 82 insertions(+)
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-ys16.xml

diff --git a/Documentation/DocBook/media/v4l/pixfmt-ys16.xml 
b/Documentation/DocBook/media/v4l/pixfmt-ys16.xml
new file mode 100644
index 000..f92d65e
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/pixfmt-ys16.xml
@@ -0,0 +1,79 @@
+
+  
+V4L2_PIX_FMT_YS16 ('YS16')
+
+  
+  
+V4L2_PIX_FMT_YS16
+Grey-scale image
+  
+  
+Description
+
+This is a signed grey-scale image with a depth of 16 bits per
+pixel. The most significant byte is stored at higher memory addresses
+(little-endian).
+
+
+  V4L2_PIX_FMT_YS16 4  4
+pixel image
+
+  
+   Byte Order.
+   Each cell is one byte.
+ 
+   
+ 
+ 
+   
+ start+0:
+ Y'00low
+ Y'00high
+ Y'01low
+ Y'01high
+ Y'02low
+ Y'02high
+ Y'03low
+ Y'03high
+   
+   
+ start+8:
+ Y'10low
+ Y'10high
+ Y'11low
+ Y'11high
+ Y'12low
+ Y'12high
+ Y'13low
+ Y'13high
+   
+   
+ start+16:
+ Y'20low
+ Y'20high
+ Y'21low
+ Y'21high
+ Y'22low
+ Y'22high
+ Y'23low
+ Y'23high
+   
+   
+ start+24:
+ Y'30low
+ Y'30high
+ Y'31low
+ Y'31high
+ Y'32low
+ Y'32high
+ Y'33low
+ Y'33high
+   
+ 
+   
+ 
+   
+  
+
+  
+
diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml 
b/Documentation/DocBook/media/v4l/pixfmt.xml
index d871245..6f7aa0e 100644
--- a/Documentation/DocBook/media/v4l/pixfmt.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt.xml
@@ -1619,6 +1619,7 @@ information.
 
 
 
+
 
 
 
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 8a018c6..c7dabaa 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1154,6 +1154,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_PIX_FMT_Y10:  descr = "10-bit Greyscale"; break;
case V4L2_PIX_FMT_Y12:  descr = "12-bit Greyscale"; break;
case V4L2_PIX_FMT_Y16:  descr = "16-bit Greyscale"; break;
+   case V4L2_PIX_FMT_YS16: descr = "16-bit Greyscale (Signed)"; 
break;
case V4L2_PIX_FMT_Y16_BE:   descr = "16-bit Greyscale BE"; break;
case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; 
break;
case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break;
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 14cd5eb..ab577dd 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -496,6 +496,7 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12  Greyscale  
   */
 #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16  Greyscale  
   */
 #define V4L2_PIX_FMT_Y16_BE  v4l2_fourcc_be('Y', '1', '6', ' ') /* 16  
Greyscale BE  */
+#define V4L2_PIX_FMT_YS16v4l2_fourcc('Y', 'S', '1', '6') /* signed 16-bit 
Greyscale */
 
 /* Grey bit-packed formats */
 #define V4L2_PIX_FMT_Y10BPACKv4l2_fourcc('Y', '1', '0', 'B') /* 10  
Greyscale bit-packed */
-- 
2.5.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


Re: [PATCH 0/8] Input: atmel_mxt_ts - output raw touch diagnostic data via V4L

2016-04-29 Thread Nick Dyer
On 22/04/2016 16:44, Mauro Carvalho Chehab wrote:
>> On the other hand, it would be a good place to tell the user that it
>> is from a touch sensor.
>>
>> Using the upcoming metadata feature wouldn't work since there is no width
>> and height in the metadata format.
>>
>> I wonder what others think about adding a new type value.
> 
> IMO, two things should be done here:
> 
> 1) Add some caps flag to help userspace to identify what's there
>on those devices;

In the patches I have written so far, I have used inputs to select between
different types of data, so I believe there's no real need for this yet.
Did you have anything else in mind?

> 2) Make sure that udev/systemd won't be naming the devnodes as
>"/dev/video";
> 
> 
> The latter one could be solved with either the new dev meta or
> with another VFL_TYPE for input systems (like VFL_TYPE_TOUCH_SENSOR)
> and use this code snippet:
> 
> diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
> b/drivers/media/v4l2-core/v4l2-dev.c
> index d8e5994cccf1..4d3e574eba49 100644
> --- a/drivers/media/v4l2-core/v4l2-dev.c
> +++ b/drivers/media/v4l2-core/v4l2-dev.c
> @@ -887,6 +887,9 @@ int __video_register_device(struct video_device *vdev, 
> int type, int nr,
> /* Use device name 'swradio' because 'sdr' was already taken. 
> */
> name_base = "swradio";
> break;
> +   case VFL_TYPE_TOUCH_SENSOR:
> +   name_base = "v4l-touch";
> +   break;
> default:
> printk(KERN_ERR "%s called with unknown type: %d\n",
>__func__, type);
> 
> 
> Such change would cause __video_register_device() to pass a different
> name_base to:
>   dev_set_name(>dev, "%s%d", name_base, vdev->num);
> 
> This way, udev/systemd will use a different name (by default, 
> /dev/v4l-touch0), and existing apps won't identify this as a
> webcam.

Thanks - this sounds like a good approach to me. I will update.
--
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/8] Input: atmel_mxt_ts - output raw touch diagnostic data via V4L

2016-04-22 Thread Nick Dyer
On 22/04/2016 15:45, Mauro Carvalho Chehab wrote:
> Em Fri, 22 Apr 2016 10:26:37 +0200
> Hans Verkuil <hverk...@xs4all.nl> escreveu:
>> On 04/21/2016 11:31 AM, Nick Dyer wrote:
>>> This is a series of patches to add diagnostic data support to the Atmel
>>> maXTouch driver. It's a rewrite of the previous implementation which output 
>>> via
>>> debugfs: it now uses a V4L2 device in a similar way to the sur40 driver.
>>>
>>> There are significant performance advantages to putting this code into the
>>> driver. The algorithm for retrieving the data has been fairly consistent 
>>> across
>>> a range of chips, with the exception of the mXT1386 series (see patch).
>>>
>>> We have a utility which can read the data and display it in a useful format:
>>> https://github.com/ndyer/heatmap/commits/heatmap-v4l
>>>
>>> These patches are also available from
>>> https://github.com/ndyer/linux/commits/diagnostic-v4l
>>>
>>> Any feedback appreciated.  
>>
>> FYI: we're working on a new buffer type for meta data:
>>
>> https://patchwork.linuxtv.org/patch/33938/
>> https://patchwork.linuxtv.org/patch/33939/
> 
> One of the things I missed on your patchset is the content of the
> new format you added (V4L2_PIX_FMT_YS16). You should be patching
> the V4L2 docbook too, in order to add it there.

OK, will do. I also see that I forgot Kconfig changes for CONFIG_VIDEO_V4L2
etc.

> That's said, if the output is really an image, I don't think it
> should be mapped via the new V4L2_BUF_TYPE_META_CAPTURE. This type of
> buffer is meant to be used on non-image metadata, like image statistics
> to feed auto whitebalance and other similar AAA algorithms.

The output is raw touch data - i.e. a rectangular grid of nodes each having
an integer value. I think it is an image in some senses, although perhaps
it's a matter of opinion!

You can see an example of a Atmel MXT capacitive touch device here (using
this patchset):
https://www.youtube.com/watch?v=Uj4T6fUCySw

There are touch devices which can deliver much higher resolution/framerate.
For example here's the data coming from a SUR40 which is an optical touch
sensor but uses V4L in a similar way:
https://www.youtube.com/watch?v=e-JNqTY_3b0

> It could still make sense to use the new device type (VFL_TYPE_META) for
> such drivers, as we don't want applications to identify those devices as
> if they are a webcam.

I agree it may be a little confusing if things like Skype start picking up
these devices. Could we #define V4L2_INPUT_TYPE_TOUCH_SENSOR to solve that
problem?
--
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] Input: atmel_mxt_ts - add support for T37 diagnostic data

2016-04-21 Thread Nick Dyer
Add function to retrieve raw references data from the diagnostic data
object

Signed-off-by: Nick Dyer <nick.d...@itdev.co.uk>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 152 +++
 1 file changed, 152 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2160512..0784a18 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -124,6 +124,17 @@ struct t9_range {
 #define MXT_COMMS_CTRL 0
 #define MXT_COMMS_CMD  1
 
+/* MXT_DEBUG_DIAGNOSTIC_T37 */
+#define MXT_DIAGNOSTIC_PAGEUP 0x01
+#define MXT_DIAGNOSTIC_DELTAS 0x10
+#define MXT_DIAGNOSTIC_SIZE128
+
+struct t37_debug {
+   u8 mode;
+   u8 page;
+   u8 data[MXT_DIAGNOSTIC_SIZE];
+};
+
 /* Define for MXT_GEN_COMMAND_T6 */
 #define MXT_BOOT_VALUE 0xa5
 #define MXT_RESET_VALUE0x01
@@ -205,6 +216,14 @@ struct mxt_object {
u8 num_report_ids;
 } __packed;
 
+struct mxt_dbg {
+   u16 t37_address;
+   u16 diag_cmd_address;
+   struct t37_debug *t37_buf;
+   unsigned int t37_pages;
+   unsigned int t37_nodes;
+};
+
 /* Each client has this additional data */
 struct mxt_data {
struct i2c_client *client;
@@ -233,6 +252,7 @@ struct mxt_data {
u8 num_touchids;
u8 multitouch;
struct t7_config t7_cfg;
+   struct mxt_dbg dbg;
 
/* Cached parameters from object table */
u16 T5_address;
@@ -2043,6 +2063,136 @@ recheck:
return 0;
 }
 
+static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x,
+  unsigned int y)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int ofs, page;
+
+   ofs = (y + (x * data->info.matrix_ysize)) * sizeof(u16);
+   page = ofs / MXT_DIAGNOSTIC_SIZE;
+   ofs %= MXT_DIAGNOSTIC_SIZE;
+
+   return get_unaligned_le16(>t37_buf[page].data[ofs]);
+}
+
+static int mxt_convert_debug_pages(struct mxt_data *data, u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   unsigned int x = 0;
+   unsigned int y = 0;
+   unsigned int i;
+
+   for (i = 0; i < dbg->t37_nodes; i++) {
+   outbuf[i] = mxt_get_debug_value(data, x, y);
+
+   /* Next value */
+   if (++x >= data->info.matrix_xsize) {
+   x = 0;
+   y++;
+   }
+   }
+
+   return 0;
+}
+
+static int mxt_read_diagnostic_debug(struct mxt_data *data, u8 mode,
+u16 *outbuf)
+{
+   struct mxt_dbg *dbg = >dbg;
+   int retries = 0;
+   int page;
+   int ret;
+   u8 cmd = mode;
+   struct t37_debug *p;
+   u8 cmd_poll;
+
+   for (page = 0; page < dbg->t37_pages; page++) {
+   p = dbg->t37_buf + page;
+
+   ret = mxt_write_reg(data->client, dbg->diag_cmd_address,
+   cmd);
+   if (ret)
+   return ret;
+
+   retries = 0;
+   msleep(20);
+wait_cmd:
+   /* Read back command byte */
+   ret = __mxt_read_reg(data->client, dbg->diag_cmd_address,
+sizeof(cmd_poll), _poll);
+   if (ret)
+   return ret;
+
+   /* Field is cleared once the command has been processed */
+   if (cmd_poll) {
+   if (retries++ > 100)
+   return -EINVAL;
+
+   msleep(20);
+   goto wait_cmd;
+   }
+
+   /* Read T37 page */
+   ret = __mxt_read_reg(data->client, dbg->t37_address,
+   sizeof(struct t37_debug), p);
+   if (ret)
+   return ret;
+
+   if ((p->mode != mode) || (p->page != page)) {
+   dev_err(>client->dev, "T37 page mismatch\n");
+   return -EINVAL;
+   }
+
+   dev_dbg(>client->dev, "%s page:%d retries:%d\n",
+   __func__, page, retries);
+
+   /* For remaining pages, write PAGEUP rather than mode */
+   cmd = MXT_DIAGNOSTIC_PAGEUP;
+   }
+
+   return mxt_convert_debug_pages(data, outbuf);
+}
+
+static void mxt_debug_init(struct mxt_data *data)
+{
+   struct mxt_dbg *dbg = >dbg;
+   struct mxt_object *object;
+
+   object = mxt_get_object(data, MXT_GEN_COMMAND_T6);
+   if (!object)
+   return;
+
+   dbg->diag_cmd_address = object->start_address + MXT_COMMAND_DIAGNOSTIC;
+
+   object = mxt_get_object(data, MXT_DEBUG_DIAGNOSTIC_T37);
+   if (!object)
+   return;
+
+   if (mxt_obj_size(object) != sizeof(struct t37_debug)) {
+ 

  1   2   >