bool dqbuf_error;
bool req_validate_error;
bool seq_wrap;
- bool time_wrap;
+ u64 time_wrap;
u64 time_wrap_offset;
unsigned perc_dropped_buffers;
enum vivid_signal_mode std_signal_mode[MAX_INPUTS];
bool touch_cap_seq_resync;
u32 touch_cap_seq_start;
u32 touch_cap_seq_count;
+ u32 touch_cap_with_seq_wrap_count;
bool touch_cap_streaming;
struct v4l2_fract timeperframe_tch_cap;
struct v4l2_pix_format tch_format;
struct task_struct *kthread_sdr_cap;
unsigned long jiffies_sdr_cap;
u32 sdr_cap_seq_offset;
+ u32 sdr_cap_seq_start;
u32 sdr_cap_seq_count;
+ u32 sdr_cap_with_seq_wrap_count;
bool sdr_cap_seq_resync;
/* RDS generator */
static int vivid_streaming_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev, ctrl_hdl_streaming);
- u64 rem;
switch (ctrl->id) {
case VIVID_CID_DQBUF_ERROR:
break;
case VIVID_CID_TIME_WRAP:
dev->time_wrap = ctrl->val;
- if (ctrl->val == 0) {
- dev->time_wrap_offset = 0;
- break;
- }
- /*
- * We want to set the time 16 seconds before the 32 bit tv_sec
- * value of struct timeval would wrap around. So first we
- * calculate ktime_get_ns() % ((1 << 32) * NSEC_PER_SEC), and
- * then we set the offset to ((1 << 32) - 16) * NSEC_PER_SEC).
- */
- div64_u64_rem(ktime_get_ns(),
- 0x100000000ULL * NSEC_PER_SEC, &rem);
- dev->time_wrap_offset =
- (0x100000000ULL - 16) * NSEC_PER_SEC - rem;
+ if (dev->time_wrap == 1)
+ dev->time_wrap = (1ULL << 63) - NSEC_PER_SEC * 16ULL;
+ else if (dev->time_wrap == 2)
+ dev->time_wrap = ((1ULL << 31) - 16) * NSEC_PER_SEC;
break;
}
return 0;
.step = 1,
};
+static const char * const vivid_ctrl_time_wrap_strings[] = {
+ "None",
+ "64 Bit",
+ "32 Bit",
+ NULL,
+};
+
static const struct v4l2_ctrl_config vivid_ctrl_time_wrap = {
.ops = &vivid_streaming_ctrl_ops,
.id = VIVID_CID_TIME_WRAP,
.name = "Wrap Timestamp",
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .max = 1,
- .step = 1,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .max = ARRAY_SIZE(vivid_ctrl_time_wrap_strings) - 2,
+ .qmenu = vivid_ctrl_time_wrap_strings,
};
if (!vid_cap_buf && !vbi_cap_buf && !meta_cap_buf)
goto update_mv;
- f_time = dev->cap_frame_period * dev->vid_cap_seq_count +
- dev->cap_stream_start + dev->time_wrap_offset;
+ f_time = ktime_get_ns() + dev->time_wrap_offset;
if (vid_cap_buf) {
v4l2_ctrl_request_setup(vid_cap_buf->vb.vb2_buf.req_obj.req,
dev->cap_seq_resync = false;
dev->jiffies_vid_cap = jiffies;
dev->cap_stream_start = ktime_get_ns();
+ if (dev->time_wrap)
+ dev->time_wrap_offset = dev->time_wrap - dev->cap_stream_start;
+ else
+ dev->time_wrap_offset = 0;
vivid_cap_update_frame_period(dev);
for (;;) {
/* Resets frame counters */
dev->out_seq_offset = 0;
- if (dev->seq_wrap)
- dev->out_seq_count = 0xffffff80U;
+ dev->out_seq_count = 0;
dev->jiffies_vid_out = jiffies;
- dev->vid_out_seq_start = dev->vbi_out_seq_start = 0;
- dev->meta_out_seq_start = 0;
dev->out_seq_resync = false;
+ if (dev->time_wrap)
+ dev->time_wrap_offset = dev->time_wrap - ktime_get_ns();
+ else
+ dev->time_wrap_offset = 0;
for (;;) {
try_to_freeze();
dev->touch_cap_seq_count = 0;
dev->touch_cap_seq_resync = false;
dev->jiffies_touch_cap = jiffies;
+ if (dev->time_wrap)
+ dev->time_wrap_offset = dev->time_wrap - ktime_get_ns();
+ else
+ dev->time_wrap_offset = 0;
for (;;) {
try_to_freeze();
}
dropped_bufs = buffers_since_start + dev->touch_cap_seq_offset - dev->touch_cap_seq_count;
dev->touch_cap_seq_count = buffers_since_start + dev->touch_cap_seq_offset;
+ dev->touch_cap_with_seq_wrap_count =
+ dev->touch_cap_seq_count - dev->touch_cap_seq_start;
vivid_thread_tch_cap_tick(dev, dropped_bufs);
return 0;
}
+ dev->touch_cap_seq_start = dev->seq_wrap * 128;
dev->kthread_touch_cap = kthread_run(vivid_thread_touch_cap, dev,
"%s-tch-cap", dev->v4l2_dev.name);
spin_unlock(&dev->slock);
if (sdr_cap_buf) {
- sdr_cap_buf->vb.sequence = dev->sdr_cap_seq_count;
+ sdr_cap_buf->vb.sequence = dev->sdr_cap_with_seq_wrap_count;
v4l2_ctrl_request_setup(sdr_cap_buf->vb.vb2_buf.req_obj.req,
&dev->ctrl_hdl_sdr_cap);
v4l2_ctrl_request_complete(sdr_cap_buf->vb.vb2_buf.req_obj.req,
/* Resets frame counters */
dev->sdr_cap_seq_offset = 0;
- if (dev->seq_wrap)
- dev->sdr_cap_seq_offset = 0xffffff80U;
+ dev->sdr_cap_seq_count = 0;
dev->jiffies_sdr_cap = jiffies;
dev->sdr_cap_seq_resync = false;
+ if (dev->time_wrap)
+ dev->time_wrap_offset = dev->time_wrap - ktime_get_ns();
+ else
+ dev->time_wrap_offset = 0;
for (;;) {
try_to_freeze();
}
dev->sdr_cap_seq_count =
buffers_since_start + dev->sdr_cap_seq_offset;
+ dev->sdr_cap_with_seq_wrap_count = dev->sdr_cap_seq_count - dev->sdr_cap_seq_start;
vivid_thread_sdr_cap_tick(dev);
mutex_unlock(&dev->mutex);
int err = 0;
dprintk(dev, 1, "%s\n", __func__);
- dev->sdr_cap_seq_count = 0;
+ dev->sdr_cap_seq_start = dev->seq_wrap * 128;
if (dev->start_streaming_error) {
dev->start_streaming_error = false;
err = -EINVAL;
__s16 *tch_buf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
- buf->vb.sequence = dev->touch_cap_seq_count;
+ buf->vb.sequence = dev->touch_cap_with_seq_wrap_count;
test_pattern = (buf->vb.sequence / TCH_SEQ_COUNT) % TEST_CASE_MAX;
test_pat_idx = buf->vb.sequence % TCH_SEQ_COUNT;