blob: 8fbe1fe27844ddfeb45cf18ded609a33173a74e6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef HWS_PCIE_H
#define HWS_PCIE_H
#include <linux/types.h>
#include <linux/compiler.h>
#include <linux/dma-mapping.h>
#include <linux/kthread.h>
#include <linux/pci.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/sizes.h>
#include <linux/atomic.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-dv-timings.h>
#include <media/videobuf2-dma-sg.h>
#include "hws_reg.h"
struct hwsmem_param {
u32 index;
u32 type;
u32 status;
};
struct hws_pix_state {
u32 width;
u32 height;
u32 fourcc; /* V4L2_PIX_FMT_* (YUYV only here) */
u32 bytesperline; /* stride */
u32 sizeimage; /* full frame */
enum v4l2_field field; /* V4L2_FIELD_NONE or INTERLACED */
enum v4l2_colorspace colorspace; /* e.g., REC709 */
enum v4l2_ycbcr_encoding ycbcr_enc; /* V4L2_YCBCR_ENC_DEFAULT */
enum v4l2_quantization quantization; /* V4L2_QUANTIZATION_LIM_RANGE */
enum v4l2_xfer_func xfer_func; /* V4L2_XFER_FUNC_DEFAULT */
bool interlaced; /* cached hardware state */
u32 half_size; /* hardware half-frame size */
};
#define UNSET (-1U)
struct hws_pcie_dev;
struct hws_adapter;
struct hws_video;
struct hwsvideo_buffer {
struct vb2_v4l2_buffer vb;
struct list_head list;
int slot;
};
struct hws_video {
/* Linkage */
struct hws_pcie_dev *parent;
struct video_device *video_device;
struct vb2_queue buffer_queue;
struct list_head capture_queue;
struct hwsvideo_buffer *active;
struct hwsvideo_buffer *next_prepared;
/* Locking */
struct mutex state_lock;
spinlock_t irq_lock; /* Protects capture_queue and active buffers. */
/* Indices */
int channel_index;
/* Color controls */
int current_brightness;
int current_contrast;
int current_saturation;
int current_hue;
/* V4L2 controls */
struct v4l2_ctrl_handler control_handler;
struct v4l2_ctrl *ctrl_brightness;
struct v4l2_ctrl *ctrl_contrast;
struct v4l2_ctrl *ctrl_saturation;
struct v4l2_ctrl *ctrl_hue;
/* Capture queue status */
struct hws_pix_state pix;
struct v4l2_dv_timings cur_dv_timings; /* last configured/notified DV timings */
u32 current_fps; /* Hz, updated by mode changes, not by read-only queries */
/* Per-channel capture state */
bool cap_active;
bool stop_requested;
u8 last_buf_half_toggle;
bool half_seen;
atomic_t sequence_number;
u32 queued_count;
/* Timeout and error handling */
u32 timeout_count;
u32 error_count;
bool window_valid;
u32 last_dma_hi;
u32 last_dma_page;
u32 last_pci_addr;
u32 last_half16;
/* Misc counters */
int signal_loss_cnt;
};
static inline void hws_set_current_dv_timings(struct hws_video *vid,
u32 width, u32 height,
bool interlaced)
{
if (!vid)
return;
vid->cur_dv_timings = (struct v4l2_dv_timings) {
.type = V4L2_DV_BT_656_1120,
.bt = {
.width = width,
.height = height,
.interlaced = interlaced,
},
};
}
struct hws_scratch_dma {
void *cpu;
dma_addr_t dma;
size_t size;
};
struct hws_pcie_dev {
/* Core objects */
struct pci_dev *pdev;
struct hws_video video[MAX_VID_CHANNELS];
/* BAR and workqueues */
void __iomem *bar0_base;
/* Device identity and capabilities */
u16 vendor_id;
u16 device_id;
u16 device_ver;
u16 hw_ver;
u32 sub_ver;
u32 port_id;
/* Tri-state support flag used by set_video_format_size(). */
u32 support_yv12;
u32 max_hw_video_buf_sz;
u8 max_channels;
u8 cur_max_video_ch;
bool start_run;
bool buf_allocated;
/* V4L2 framework objects */
struct v4l2_device v4l2_device;
/* Kernel thread */
struct task_struct *main_task;
struct hws_scratch_dma scratch_vid[MAX_VID_CHANNELS];
bool suspended;
int irq;
/* Error flags */
int pci_lost;
};
#endif
|