| .. | .. |
|---|
| 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)); |
|---|