Hi Vandana, This looks really good. I have a few very small comments (I'd have changed it myself, but we're in the code freeze period so there is time for a v9): On 11/25/19 5:23 AM, Vandana BN wrote: > Support to emulate touch devices in vivid driver. > It generates touch patterns simulating single tap, double tap, triple > tap, move from left to right, zoom in, zoom out, palm press simulating > large area being pressed on screen, and simulating 16 different > simultaneous touch points.The values generated are based on > behavior of the rmi_f54 driver. > > Signed-off-by: Vandana BN <bnvandana@xxxxxxxxx> > --- > drivers/media/platform/vivid/Makefile | 3 +- > drivers/media/platform/vivid/vivid-core.c | 164 ++++++++- > drivers/media/platform/vivid/vivid-core.h | 20 ++ > drivers/media/platform/vivid/vivid-ctrls.c | 11 + > .../platform/vivid/vivid-kthread-touch.c | 181 ++++++++++ > .../platform/vivid/vivid-kthread-touch.h | 13 + > .../media/platform/vivid/vivid-touch-cap.c | 320 ++++++++++++++++++ > .../media/platform/vivid/vivid-touch-cap.h | 38 +++ > 8 files changed, 737 insertions(+), 13 deletions(-) > create mode 100644 drivers/media/platform/vivid/vivid-kthread-touch.c > create mode 100644 drivers/media/platform/vivid/vivid-kthread-touch.h > create mode 100644 drivers/media/platform/vivid/vivid-touch-cap.c > create mode 100644 drivers/media/platform/vivid/vivid-touch-cap.h > <snip> > +void vivid_fillbuff_tch(struct vivid_dev *dev, struct vivid_buffer *buf) > +{ > + struct v4l2_pix_format *f = &dev->tch_format; > + int size = f->width * f->height; > + int x, y, xstart, ystart, offset_x, offset_y; > + unsigned int test_pattern, test_pat_idx, rand; > + > + __s16 *tch_buf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0); > + > + buf->vb.sequence = dev->touch_cap_seq_count; > + test_pattern = (buf->vb.sequence / TCH_SEQ_COUNT) % TEST_CASE_MAX; > + test_pat_idx = buf->vb.sequence % TCH_SEQ_COUNT; > + > + vivid_fill_buff_noise(tch_buf, size); > + > + if (test_pat_idx >= TCH_PATTERN_COUNT) > + return; > + > + if (test_pat_idx == 0) > + dev->tch_pat_random = get_random_int(); > + rand = dev->tch_pat_random; > + > + switch (test_pattern) { > + case SINGLE_TAP: > + if (test_pat_idx == 5) Let's change 5 to TCH_PATTERN_COUNT / 2 > + vivid_tch_buf_set(f, tch_buf, rand % size); > + break; > + case DOUBLE_TAP: > + if (test_pat_idx == 3 || test_pat_idx == 6) And 3 and 6 to: TCH_PATTERN_COUNT / 3 and 2 * TCH_PATTERN_COUNT / 3 > + vivid_tch_buf_set(f, tch_buf, rand % size); > + break; > + case TRIPLE_TAP: > + if (test_pat_idx == 3 || test_pat_idx == 6 || test_pat_idx == 9) TCH_PATTERN_COUNT / 4, 2 * TCH_PATTERN_COUNT / 4, 3 * TCH_PATTERN_COUNT / 4 > + vivid_tch_buf_set(f, tch_buf, rand % size); > + break; > + case MOVE_LEFT_TO_RIGHT: > + vivid_tch_buf_set(f, tch_buf, > + (rand % f->height) * f->width + > + test_pat_idx * (f->width / 10)); 10 -> TCH_PATTERN_COUNT Regards, Hans > + break; > + case ZOOM_IN: > + x = f->width / 2; > + y = f->height / 2; > + offset_x = ((TCH_PATTERN_COUNT - 1 - test_pat_idx) * x) / > + TCH_PATTERN_COUNT; > + offset_y = ((TCH_PATTERN_COUNT - 1 - test_pat_idx) * y) / > + TCH_PATTERN_COUNT; > + vivid_tch_buf_set(f, tch_buf, > + (x - offset_x) + f->width * (y - offset_y)); > + vivid_tch_buf_set(f, tch_buf, > + (x + offset_x) + f->width * (y + offset_y)); > + break; > + case ZOOM_OUT: > + x = f->width / 2; > + y = f->height / 2; > + offset_x = (test_pat_idx * x) / TCH_PATTERN_COUNT; > + offset_y = (test_pat_idx * y) / TCH_PATTERN_COUNT; > + vivid_tch_buf_set(f, tch_buf, > + (x - offset_x) + f->width * (y - offset_y)); > + vivid_tch_buf_set(f, tch_buf, > + (x + offset_x) + f->width * (y + offset_y)); > + break; > + case PALM_PRESS: > + for (x = 0; x < f->width; x++) > + for (y = f->height / 2; y < f->height; y++) > + vivid_tch_buf_set(f, tch_buf, x + f->width * y); > + break; > + case MULTIPLE_PRESS: > + /* 16 pressure points */ > + for (y = 0; y < 4; y++) { > + for (x = 0; x < 4; x++) { > + ystart = (y * f->height) / 4 + f->height / 8; > + xstart = (x * f->width) / 4 + f->width / 8; > + vivid_tch_buf_set(f, tch_buf, > + ystart * f->width + xstart); > + } > + } > + break; > + } > +#ifdef __BIG_ENDIAN__ > + for (x = 0; x < size; x++) > + tch_buf[x] = (__force s16)__cpu_to_le16((u16)tch_buf[x]); > +#endif > +} > diff --git a/drivers/media/platform/vivid/vivid-touch-cap.h b/drivers/media/platform/vivid/vivid-touch-cap.h > new file mode 100644 > index 000000000000..761050b652eb > --- /dev/null > +++ b/drivers/media/platform/vivid/vivid-touch-cap.h > @@ -0,0 +1,38 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * vivid-touch-cap.h - touch support functions. > + */ > +#ifndef _VIVID_TOUCH_CAP_H_ > +#define _VIVID_TOUCH_CAP_H_ > + > +#define VIVID_TCH_HEIGHT 12 > +#define VIVID_TCH_WIDTH 21 > +#define VIVID_MIN_PRESSURE 180 > +#define VIVID_PRESSURE_LIMIT 40 > +#define TCH_SEQ_COUNT 16 > +#define TCH_PATTERN_COUNT 12 > + > +enum vivid_tch_test { > + SINGLE_TAP, > + DOUBLE_TAP, > + TRIPLE_TAP, > + MOVE_LEFT_TO_RIGHT, > + ZOOM_IN, > + ZOOM_OUT, > + PALM_PRESS, > + MULTIPLE_PRESS, > + TEST_CASE_MAX > +}; > + > +extern const struct vb2_ops vivid_touch_cap_qops; > + > +int vivid_enum_fmt_tch(struct file *file, void *priv, struct v4l2_fmtdesc *f); > +int vivid_g_fmt_tch(struct file *file, void *priv, struct v4l2_format *f); > +int vivid_enum_input_tch(struct file *file, void *priv, struct v4l2_input *inp); > +int vivid_g_input_tch(struct file *file, void *priv, unsigned int *i); > +int vivid_s_input_tch(struct file *file, void *priv, unsigned int i); > +void vivid_fillbuff_tch(struct vivid_dev *dev, struct vivid_buffer *buf); > +int vivid_set_touch(struct vivid_dev *dev, unsigned int i); > +int vivid_g_parm_tch(struct file *file, void *priv, > + struct v4l2_streamparm *parm); > +#endif >