.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2012-2015 Synaptics Incorporated |
---|
3 | 4 | * Copyright (C) 2016 Zodiac Inflight Innovations |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify it |
---|
6 | | - * under the terms of the GNU General Public License version 2 as published by |
---|
7 | | - * the Free Software Foundation. |
---|
8 | 5 | */ |
---|
9 | 6 | |
---|
10 | 7 | #include <linux/kernel.h> |
---|
.. | .. |
---|
26 | 23 | #define F54_FIFO_OFFSET 1 |
---|
27 | 24 | #define F54_NUM_TX_OFFSET 1 |
---|
28 | 25 | #define F54_NUM_RX_OFFSET 0 |
---|
| 26 | + |
---|
| 27 | +/* |
---|
| 28 | + * The smbus protocol can read only 32 bytes max at a time. |
---|
| 29 | + * But this should be fine for i2c/spi as well. |
---|
| 30 | + */ |
---|
| 31 | +#define F54_REPORT_DATA_SIZE 32 |
---|
29 | 32 | |
---|
30 | 33 | /* F54 commands */ |
---|
31 | 34 | #define F54_GET_REPORT 1 |
---|
.. | .. |
---|
84 | 87 | = "Full Raw Capacitance RX Offset Removed", |
---|
85 | 88 | }; |
---|
86 | 89 | |
---|
87 | | -struct rmi_f54_reports { |
---|
88 | | - int start; |
---|
89 | | - int size; |
---|
90 | | -}; |
---|
91 | | - |
---|
92 | 90 | struct f54_data { |
---|
93 | 91 | struct rmi_function *fn; |
---|
94 | 92 | |
---|
.. | .. |
---|
101 | 99 | enum rmi_f54_report_type report_type; |
---|
102 | 100 | u8 *report_data; |
---|
103 | 101 | int report_size; |
---|
104 | | - struct rmi_f54_reports standard_report[2]; |
---|
105 | 102 | |
---|
106 | 103 | bool is_busy; |
---|
107 | 104 | struct mutex status_mutex; |
---|
.. | .. |
---|
119 | 116 | struct video_device vdev; |
---|
120 | 117 | struct vb2_queue queue; |
---|
121 | 118 | struct mutex lock; |
---|
| 119 | + u32 sequence; |
---|
122 | 120 | int input; |
---|
123 | 121 | enum rmi_f54_report_type inputs[F54_MAX_REPORT_TYPE]; |
---|
124 | 122 | }; |
---|
.. | .. |
---|
293 | 291 | |
---|
294 | 292 | static void rmi_f54_buffer_queue(struct vb2_buffer *vb) |
---|
295 | 293 | { |
---|
| 294 | + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
---|
296 | 295 | struct f54_data *f54 = vb2_get_drv_priv(vb->vb2_queue); |
---|
297 | 296 | u16 *ptr; |
---|
298 | 297 | enum vb2_buffer_state state; |
---|
.. | .. |
---|
301 | 300 | |
---|
302 | 301 | mutex_lock(&f54->status_mutex); |
---|
303 | 302 | |
---|
| 303 | + vb2_set_plane_payload(vb, 0, 0); |
---|
304 | 304 | reptype = rmi_f54_get_reptype(f54, f54->input); |
---|
305 | 305 | if (reptype == F54_REPORT_NONE) { |
---|
306 | 306 | state = VB2_BUF_STATE_ERROR; |
---|
.. | .. |
---|
347 | 347 | data_done: |
---|
348 | 348 | mutex_unlock(&f54->data_mutex); |
---|
349 | 349 | done: |
---|
| 350 | + vb->timestamp = ktime_get_ns(); |
---|
| 351 | + vbuf->field = V4L2_FIELD_NONE; |
---|
| 352 | + vbuf->sequence = f54->sequence++; |
---|
350 | 353 | vb2_buffer_done(vb, state); |
---|
351 | 354 | mutex_unlock(&f54->status_mutex); |
---|
| 355 | +} |
---|
| 356 | + |
---|
| 357 | +static void rmi_f54_stop_streaming(struct vb2_queue *q) |
---|
| 358 | +{ |
---|
| 359 | + struct f54_data *f54 = vb2_get_drv_priv(q); |
---|
| 360 | + |
---|
| 361 | + f54->sequence = 0; |
---|
352 | 362 | } |
---|
353 | 363 | |
---|
354 | 364 | /* V4L2 structures */ |
---|
355 | 365 | static const struct vb2_ops rmi_f54_queue_ops = { |
---|
356 | 366 | .queue_setup = rmi_f54_queue_setup, |
---|
357 | 367 | .buf_queue = rmi_f54_buffer_queue, |
---|
| 368 | + .stop_streaming = rmi_f54_stop_streaming, |
---|
358 | 369 | .wait_prepare = vb2_ops_wait_prepare, |
---|
359 | 370 | .wait_finish = vb2_ops_wait_finish, |
---|
360 | 371 | }; |
---|
.. | .. |
---|
366 | 377 | .ops = &rmi_f54_queue_ops, |
---|
367 | 378 | .mem_ops = &vb2_vmalloc_memops, |
---|
368 | 379 | .timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC, |
---|
369 | | - .min_buffers_needed = 1, |
---|
370 | 380 | }; |
---|
371 | 381 | |
---|
372 | 382 | static int rmi_f54_vidioc_querycap(struct file *file, void *priv, |
---|
.. | .. |
---|
456 | 466 | static int rmi_f54_vidioc_enum_fmt(struct file *file, void *priv, |
---|
457 | 467 | struct v4l2_fmtdesc *fmt) |
---|
458 | 468 | { |
---|
| 469 | + struct f54_data *f54 = video_drvdata(file); |
---|
| 470 | + |
---|
459 | 471 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
---|
460 | 472 | return -EINVAL; |
---|
461 | 473 | |
---|
462 | | - switch (fmt->index) { |
---|
463 | | - case 0: |
---|
464 | | - fmt->pixelformat = V4L2_TCH_FMT_DELTA_TD16; |
---|
465 | | - break; |
---|
466 | | - |
---|
467 | | - case 1: |
---|
468 | | - fmt->pixelformat = V4L2_TCH_FMT_DELTA_TD08; |
---|
469 | | - break; |
---|
470 | | - |
---|
471 | | - case 2: |
---|
472 | | - fmt->pixelformat = V4L2_TCH_FMT_TU16; |
---|
473 | | - break; |
---|
474 | | - |
---|
475 | | - default: |
---|
| 474 | + if (fmt->index) |
---|
476 | 475 | return -EINVAL; |
---|
477 | | - } |
---|
| 476 | + |
---|
| 477 | + fmt->pixelformat = f54->format.pixelformat; |
---|
478 | 478 | |
---|
479 | 479 | return 0; |
---|
480 | 480 | } |
---|
.. | .. |
---|
529 | 529 | struct f54_data *f54 = container_of(work, struct f54_data, work.work); |
---|
530 | 530 | struct rmi_function *fn = f54->fn; |
---|
531 | 531 | u8 fifo[2]; |
---|
532 | | - struct rmi_f54_reports *report; |
---|
533 | 532 | int report_size; |
---|
534 | 533 | u8 command; |
---|
535 | | - u8 *data; |
---|
536 | 534 | int error; |
---|
| 535 | + int i; |
---|
537 | 536 | |
---|
538 | | - data = f54->report_data; |
---|
539 | 537 | report_size = rmi_f54_get_report_size(f54); |
---|
540 | 538 | if (report_size == 0) { |
---|
541 | 539 | dev_err(&fn->dev, "Bad report size, report type=%d\n", |
---|
.. | .. |
---|
543 | 541 | error = -EINVAL; |
---|
544 | 542 | goto error; /* retry won't help */ |
---|
545 | 543 | } |
---|
546 | | - f54->standard_report[0].size = report_size; |
---|
547 | | - report = f54->standard_report; |
---|
548 | 544 | |
---|
549 | 545 | mutex_lock(&f54->data_mutex); |
---|
550 | 546 | |
---|
.. | .. |
---|
569 | 565 | |
---|
570 | 566 | rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Get report command completed, reading data\n"); |
---|
571 | 567 | |
---|
572 | | - report_size = 0; |
---|
573 | | - for (; report->size; report++) { |
---|
574 | | - fifo[0] = report->start & 0xff; |
---|
575 | | - fifo[1] = (report->start >> 8) & 0xff; |
---|
| 568 | + for (i = 0; i < report_size; i += F54_REPORT_DATA_SIZE) { |
---|
| 569 | + int size = min(F54_REPORT_DATA_SIZE, report_size - i); |
---|
| 570 | + |
---|
| 571 | + fifo[0] = i & 0xff; |
---|
| 572 | + fifo[1] = i >> 8; |
---|
576 | 573 | error = rmi_write_block(fn->rmi_dev, |
---|
577 | 574 | fn->fd.data_base_addr + F54_FIFO_OFFSET, |
---|
578 | 575 | fifo, sizeof(fifo)); |
---|
.. | .. |
---|
582 | 579 | } |
---|
583 | 580 | |
---|
584 | 581 | error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr + |
---|
585 | | - F54_REPORT_DATA_OFFSET, data, |
---|
586 | | - report->size); |
---|
| 582 | + F54_REPORT_DATA_OFFSET, |
---|
| 583 | + f54->report_data + i, size); |
---|
587 | 584 | if (error) { |
---|
588 | 585 | dev_err(&fn->dev, "%s: read [%d bytes] returned %d\n", |
---|
589 | | - __func__, report->size, error); |
---|
| 586 | + __func__, size, error); |
---|
590 | 587 | goto abort; |
---|
591 | 588 | } |
---|
592 | | - data += report->size; |
---|
593 | | - report_size += report->size; |
---|
594 | 589 | } |
---|
595 | 590 | |
---|
596 | 591 | abort: |
---|
.. | .. |
---|
692 | 687 | return -ENOMEM; |
---|
693 | 688 | |
---|
694 | 689 | rmi_f54_create_input_map(f54); |
---|
| 690 | + rmi_f54_set_input(f54, 0); |
---|
695 | 691 | |
---|
696 | 692 | /* register video device */ |
---|
697 | 693 | strlcpy(f54->v4l2.name, F54_NAME, sizeof(f54->v4l2.name)); |
---|