^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * vivid-touch-cap.c - touch support functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "vivid-core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "vivid-kthread-touch.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "vivid-vid-common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "vivid-touch-cap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) static int touch_cap_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) unsigned int *nplanes, unsigned int sizes[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) struct device *alloc_devs[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct vivid_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) struct v4l2_pix_format *f = &dev->tch_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) unsigned int size = f->sizeimage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) if (*nplanes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) if (sizes[0] < size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) sizes[0] = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (vq->num_buffers + *nbuffers < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *nbuffers = 2 - vq->num_buffers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *nplanes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static int touch_cap_buf_prepare(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct v4l2_pix_format *f = &dev->tch_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) unsigned int size = f->sizeimage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (dev->buf_prepare_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Error injection: test what happens if buf_prepare() returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) dev->buf_prepare_error = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (vb2_plane_size(vb, 0) < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) __func__, vb2_plane_size(vb, 0), size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) vb2_set_plane_payload(vb, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static void touch_cap_buf_queue(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) vbuf->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) spin_lock(&dev->slock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) list_add_tail(&buf->list, &dev->touch_cap_active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) spin_unlock(&dev->slock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static int touch_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct vivid_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) dev->touch_cap_seq_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (dev->start_streaming_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) dev->start_streaming_error = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) err = vivid_start_generating_touch_cap(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct vivid_buffer *buf, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) list_for_each_entry_safe(buf, tmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) &dev->touch_cap_active, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) list_del(&buf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) vb2_buffer_done(&buf->vb.vb2_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) VB2_BUF_STATE_QUEUED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* abort streaming and wait for last buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static void touch_cap_stop_streaming(struct vb2_queue *vq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct vivid_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) vivid_stop_generating_touch_cap(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static void touch_cap_buf_request_complete(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_touch_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) const struct vb2_ops vivid_touch_cap_qops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .queue_setup = touch_cap_queue_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .buf_prepare = touch_cap_buf_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .buf_queue = touch_cap_buf_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) .start_streaming = touch_cap_start_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .stop_streaming = touch_cap_stop_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) .buf_request_complete = touch_cap_buf_request_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) .wait_prepare = vb2_ops_wait_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .wait_finish = vb2_ops_wait_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int vivid_enum_fmt_tch(struct file *file, void *priv, struct v4l2_fmtdesc *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (f->index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int vivid_g_fmt_tch(struct file *file, void *priv, struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (dev->multiplanar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) f->fmt.pix = dev->tch_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int vivid_g_fmt_tch_mplane(struct file *file, void *priv, struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct v4l2_format sp_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (!dev->multiplanar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) sp_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) sp_fmt.fmt.pix = dev->tch_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) fmt_sp2mp(&sp_fmt, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int vivid_g_parm_tch(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct v4l2_streamparm *parm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (parm->type != (dev->multiplanar ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) V4L2_BUF_TYPE_VIDEO_CAPTURE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) parm->parm.capture.timeperframe = dev->timeperframe_tch_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) parm->parm.capture.readbuffers = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int vivid_enum_input_tch(struct file *file, void *priv, struct v4l2_input *inp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (inp->index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) inp->type = V4L2_INPUT_TYPE_TOUCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) strscpy(inp->name, "Vivid Touch", sizeof(inp->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) inp->capabilities = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int vivid_g_input_tch(struct file *file, void *priv, unsigned int *i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) *i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int vivid_set_touch(struct vivid_dev *dev, unsigned int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct v4l2_pix_format *f = &dev->tch_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) f->pixelformat = V4L2_TCH_FMT_DELTA_TD16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) f->width = VIVID_TCH_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) f->height = VIVID_TCH_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) f->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) f->colorspace = V4L2_COLORSPACE_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) f->bytesperline = f->width * sizeof(s16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) f->sizeimage = f->width * f->height * sizeof(s16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int vivid_s_input_tch(struct file *file, void *priv, unsigned int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return vivid_set_touch(video_drvdata(file), i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static void vivid_fill_buff_noise(__s16 *tch_buf, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Fill 10% of the values within range -3 and 3, zero the others */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) for (i = 0; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) unsigned int rand = get_random_int();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (rand % 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) tch_buf[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) tch_buf[i] = (rand / 10) % 7 - 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static inline int get_random_pressure(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return get_random_int() % VIVID_PRESSURE_LIMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static void vivid_tch_buf_set(struct v4l2_pix_format *f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) __s16 *tch_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) unsigned int x = index % f->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) unsigned int y = index / f->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) unsigned int offset = VIVID_MIN_PRESSURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) tch_buf[index] = offset + get_random_pressure();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) offset /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) tch_buf[index - 1] = offset + get_random_pressure();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (x < f->width - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) tch_buf[index + 1] = offset + get_random_pressure();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) tch_buf[index - f->width] = offset + get_random_pressure();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (y < f->height - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) tch_buf[index + f->width] = offset + get_random_pressure();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) offset /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (x && y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) tch_buf[index - 1 - f->width] = offset + get_random_pressure();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (x < f->width - 1 && y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) tch_buf[index + 1 - f->width] = offset + get_random_pressure();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (x && y < f->height - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) tch_buf[index - 1 + f->width] = offset + get_random_pressure();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (x < f->width - 1 && y < f->height - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) tch_buf[index + 1 + f->width] = offset + get_random_pressure();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) void vivid_fillbuff_tch(struct vivid_dev *dev, struct vivid_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct v4l2_pix_format *f = &dev->tch_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) int size = f->width * f->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) int x, y, xstart, ystart, offset_x, offset_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) unsigned int test_pattern, test_pat_idx, rand;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) __s16 *tch_buf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) buf->vb.sequence = dev->touch_cap_seq_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) test_pattern = (buf->vb.sequence / TCH_SEQ_COUNT) % TEST_CASE_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) test_pat_idx = buf->vb.sequence % TCH_SEQ_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) vivid_fill_buff_noise(tch_buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (test_pat_idx >= TCH_PATTERN_COUNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (test_pat_idx == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) dev->tch_pat_random = get_random_int();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) rand = dev->tch_pat_random;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) switch (test_pattern) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) case SINGLE_TAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (test_pat_idx == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) vivid_tch_buf_set(f, tch_buf, rand % size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) case DOUBLE_TAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (test_pat_idx == 2 || test_pat_idx == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) vivid_tch_buf_set(f, tch_buf, rand % size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) case TRIPLE_TAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (test_pat_idx == 2 || test_pat_idx == 4 || test_pat_idx == 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) vivid_tch_buf_set(f, tch_buf, rand % size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) case MOVE_LEFT_TO_RIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) vivid_tch_buf_set(f, tch_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) (rand % f->height) * f->width +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) test_pat_idx *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) (f->width / TCH_PATTERN_COUNT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) case ZOOM_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) x = f->width / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) y = f->height / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) offset_x = ((TCH_PATTERN_COUNT - 1 - test_pat_idx) * x) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) TCH_PATTERN_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) offset_y = ((TCH_PATTERN_COUNT - 1 - test_pat_idx) * y) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) TCH_PATTERN_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) vivid_tch_buf_set(f, tch_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) (x - offset_x) + f->width * (y - offset_y));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) vivid_tch_buf_set(f, tch_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) (x + offset_x) + f->width * (y + offset_y));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) case ZOOM_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) x = f->width / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) y = f->height / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) offset_x = (test_pat_idx * x) / TCH_PATTERN_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) offset_y = (test_pat_idx * y) / TCH_PATTERN_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) vivid_tch_buf_set(f, tch_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) (x - offset_x) + f->width * (y - offset_y));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) vivid_tch_buf_set(f, tch_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) (x + offset_x) + f->width * (y + offset_y));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case PALM_PRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) for (x = 0; x < f->width; x++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) for (y = f->height / 2; y < f->height; y++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) tch_buf[x + f->width * y] = VIVID_MIN_PRESSURE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) get_random_pressure();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) case MULTIPLE_PRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* 16 pressure points */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) for (y = 0; y < 4; y++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) for (x = 0; x < 4; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ystart = (y * f->height) / 4 + f->height / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) xstart = (x * f->width) / 4 + f->width / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) vivid_tch_buf_set(f, tch_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) ystart * f->width + xstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) #ifdef __BIG_ENDIAN__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) for (x = 0; x < size; x++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) tch_buf[x] = (__force s16)__cpu_to_le16((u16)tch_buf[x]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }