1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
2 | /* |
3 | * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com> |
4 | * |
5 | * Original author: |
6 | * Ben Collins <bcollins@ubuntu.com> |
7 | * |
8 | * Additional work by: |
9 | * John Brooks <john.brooks@bluecherry.net> |
10 | */ |
11 | |
12 | #ifndef __SOLO6X10_H |
13 | #define __SOLO6X10_H |
14 | |
15 | #include <linux/pci.h> |
16 | #include <linux/i2c.h> |
17 | #include <linux/mutex.h> |
18 | #include <linux/list.h> |
19 | #include <linux/wait.h> |
20 | #include <linux/stringify.h> |
21 | #include <linux/io.h> |
22 | #include <linux/atomic.h> |
23 | #include <linux/slab.h> |
24 | #include <linux/videodev2.h> |
25 | #include <linux/gpio/driver.h> |
26 | |
27 | #include <media/v4l2-dev.h> |
28 | #include <media/v4l2-device.h> |
29 | #include <media/v4l2-ctrls.h> |
30 | #include <media/videobuf2-v4l2.h> |
31 | |
32 | #include "solo6x10-regs.h" |
33 | |
34 | #ifndef PCI_VENDOR_ID_SOFTLOGIC |
35 | #define PCI_VENDOR_ID_SOFTLOGIC 0x9413 |
36 | #define PCI_DEVICE_ID_SOLO6010 0x6010 |
37 | #define PCI_DEVICE_ID_SOLO6110 0x6110 |
38 | #endif |
39 | |
40 | #ifndef PCI_VENDOR_ID_BLUECHERRY |
41 | #define PCI_VENDOR_ID_BLUECHERRY 0x1BB3 |
42 | /* Neugent Softlogic 6010 based cards */ |
43 | #define PCI_DEVICE_ID_NEUSOLO_4 0x4304 |
44 | #define PCI_DEVICE_ID_NEUSOLO_9 0x4309 |
45 | #define PCI_DEVICE_ID_NEUSOLO_16 0x4310 |
46 | /* Bluecherry Softlogic 6010 based cards */ |
47 | #define PCI_DEVICE_ID_BC_SOLO_4 0x4E04 |
48 | #define PCI_DEVICE_ID_BC_SOLO_9 0x4E09 |
49 | #define PCI_DEVICE_ID_BC_SOLO_16 0x4E10 |
50 | /* Bluecherry Softlogic 6110 based cards */ |
51 | #define PCI_DEVICE_ID_BC_6110_4 0x5304 |
52 | #define PCI_DEVICE_ID_BC_6110_8 0x5308 |
53 | #define PCI_DEVICE_ID_BC_6110_16 0x5310 |
54 | #endif /* Bluecherry */ |
55 | |
56 | /* Used in pci_device_id, and solo_dev->type */ |
57 | #define SOLO_DEV_6010 0 |
58 | #define SOLO_DEV_6110 1 |
59 | |
60 | #define SOLO6X10_NAME "solo6x10" |
61 | |
62 | #define SOLO_MAX_CHANNELS 16 |
63 | |
64 | #define SOLO6X10_VERSION "3.0.0" |
65 | |
66 | /* |
67 | * The SOLO6x10 actually has 8 i2c channels, but we only use 2. |
68 | * 0 - Techwell chip(s) |
69 | * 1 - SAA7128 |
70 | */ |
71 | #define SOLO_I2C_ADAPTERS 2 |
72 | #define SOLO_I2C_TW 0 |
73 | #define SOLO_I2C_SAA 1 |
74 | |
75 | /* DMA Engine setup */ |
76 | #define SOLO_NR_P2M 4 |
77 | #define SOLO_NR_P2M_DESC 256 |
78 | #define SOLO_P2M_DESC_SIZE (SOLO_NR_P2M_DESC * 16) |
79 | |
80 | /* Encoder standard modes */ |
81 | #define SOLO_ENC_MODE_CIF 2 |
82 | #define SOLO_ENC_MODE_HD1 1 |
83 | #define SOLO_ENC_MODE_D1 9 |
84 | |
85 | #define SOLO_DEFAULT_QP 3 |
86 | |
87 | #define SOLO_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000) |
88 | #define V4L2_CID_MOTION_TRACE (SOLO_CID_CUSTOM_BASE+2) |
89 | #define V4L2_CID_OSD_TEXT (SOLO_CID_CUSTOM_BASE+3) |
90 | |
91 | /* |
92 | * Motion thresholds are in a table of 64x64 samples, with |
93 | * each sample representing 16x16 pixels of the source. In |
94 | * effect, 44x30 samples are used for NTSC, and 44x36 for PAL. |
95 | * The 5th sample on the 10th row is (10*64)+5 = 645. |
96 | * |
97 | * Internally it is stored as a 45x45 array (45*16 = 720, which is the |
98 | * maximum PAL/NTSC width). |
99 | */ |
100 | #define SOLO_MOTION_SZ (45) |
101 | |
102 | enum SOLO_I2C_STATE { |
103 | IIC_STATE_IDLE, |
104 | IIC_STATE_START, |
105 | IIC_STATE_READ, |
106 | IIC_STATE_WRITE, |
107 | IIC_STATE_STOP |
108 | }; |
109 | |
110 | /* Defined in Table 4-16, Page 68-69 of the 6010 Datasheet */ |
111 | struct solo_p2m_desc { |
112 | u32 ctrl; |
113 | u32 cfg; |
114 | u32 dma_addr; |
115 | u32 ext_addr; |
116 | }; |
117 | |
118 | struct solo_p2m_dev { |
119 | struct mutex mutex; |
120 | struct completion completion; |
121 | int desc_count; |
122 | int desc_idx; |
123 | struct solo_p2m_desc *descs; |
124 | int error; |
125 | }; |
126 | |
127 | #define OSD_TEXT_MAX 44 |
128 | |
129 | struct solo_vb2_buf { |
130 | struct vb2_v4l2_buffer vb; |
131 | struct list_head list; |
132 | }; |
133 | |
134 | enum solo_enc_types { |
135 | SOLO_ENC_TYPE_STD, |
136 | SOLO_ENC_TYPE_EXT, |
137 | }; |
138 | |
139 | struct solo_enc_dev { |
140 | struct solo_dev *solo_dev; |
141 | /* V4L2 Items */ |
142 | struct v4l2_ctrl_handler hdl; |
143 | struct v4l2_ctrl *md_thresholds; |
144 | struct video_device *vfd; |
145 | /* General accounting */ |
146 | struct mutex lock; |
147 | spinlock_t motion_lock; |
148 | u8 ch; |
149 | u8 mode, gop, qp, interlaced, interval; |
150 | u8 bw_weight; |
151 | u16 motion_thresh; |
152 | bool motion_global; |
153 | bool motion_enabled; |
154 | u16 width; |
155 | u16 height; |
156 | |
157 | /* OSD buffers */ |
158 | char osd_text[OSD_TEXT_MAX + 1]; |
159 | u8 osd_buf[SOLO_EOSD_EXT_SIZE_MAX] |
160 | __aligned(4); |
161 | |
162 | /* VOP stuff */ |
163 | u8 vop[64]; |
164 | int vop_len; |
165 | u8 [1024]; |
166 | int jpeg_len; |
167 | |
168 | u32 fmt; |
169 | enum solo_enc_types type; |
170 | u32 sequence; |
171 | struct vb2_queue vidq; |
172 | struct list_head vidq_active; |
173 | int desc_count; |
174 | int desc_nelts; |
175 | struct solo_p2m_desc *desc_items; |
176 | dma_addr_t desc_dma; |
177 | spinlock_t av_lock; |
178 | }; |
179 | |
180 | /* The SOLO6x10 PCI Device */ |
181 | struct solo_dev { |
182 | /* General stuff */ |
183 | struct pci_dev *pdev; |
184 | int type; |
185 | unsigned int time_sync; |
186 | unsigned int usec_lsb; |
187 | unsigned int clock_mhz; |
188 | u8 __iomem *reg_base; |
189 | int nr_chans; |
190 | int nr_ext; |
191 | u32 irq_mask; |
192 | u32 motion_mask; |
193 | struct v4l2_device v4l2_dev; |
194 | #ifdef CONFIG_GPIOLIB |
195 | /* GPIO */ |
196 | struct gpio_chip gpio_dev; |
197 | #endif |
198 | |
199 | /* tw28xx accounting */ |
200 | u8 tw2865, tw2864, tw2815; |
201 | u8 tw28_cnt; |
202 | |
203 | /* i2c related items */ |
204 | struct i2c_adapter i2c_adap[SOLO_I2C_ADAPTERS]; |
205 | enum SOLO_I2C_STATE i2c_state; |
206 | struct mutex i2c_mutex; |
207 | int i2c_id; |
208 | wait_queue_head_t i2c_wait; |
209 | struct i2c_msg *i2c_msg; |
210 | unsigned int i2c_msg_num; |
211 | unsigned int i2c_msg_ptr; |
212 | |
213 | /* P2M DMA Engine */ |
214 | struct solo_p2m_dev p2m_dev[SOLO_NR_P2M]; |
215 | atomic_t p2m_count; |
216 | int p2m_jiffies; |
217 | unsigned int p2m_timeouts; |
218 | |
219 | /* V4L2 Display items */ |
220 | struct video_device *vfd; |
221 | unsigned int erasing; |
222 | unsigned int frame_blank; |
223 | u8 cur_disp_ch; |
224 | wait_queue_head_t disp_thread_wait; |
225 | struct v4l2_ctrl_handler disp_hdl; |
226 | |
227 | /* V4L2 Encoder items */ |
228 | struct solo_enc_dev *v4l2_enc[SOLO_MAX_CHANNELS]; |
229 | u16 enc_bw_remain; |
230 | /* IDX into hw mp4 encoder */ |
231 | u8 enc_idx; |
232 | |
233 | /* Current video settings */ |
234 | u32 video_type; |
235 | u16 video_hsize, video_vsize; |
236 | u16 vout_hstart, vout_vstart; |
237 | u16 vin_hstart, vin_vstart; |
238 | u8 fps; |
239 | |
240 | /* JPEG Qp setting */ |
241 | spinlock_t jpeg_qp_lock; |
242 | u32 jpeg_qp[2]; |
243 | |
244 | /* Audio components */ |
245 | struct snd_card *snd_card; |
246 | struct snd_pcm *snd_pcm; |
247 | atomic_t snd_users; |
248 | int g723_hw_idx; |
249 | |
250 | /* sysfs stuffs */ |
251 | struct device dev; |
252 | int sdram_size; |
253 | struct bin_attribute sdram_attr; |
254 | unsigned int sys_config; |
255 | |
256 | /* Ring thread */ |
257 | struct task_struct *ring_thread; |
258 | wait_queue_head_t ring_thread_wait; |
259 | |
260 | /* VOP_HEADER handling */ |
261 | void *vh_buf; |
262 | dma_addr_t vh_dma; |
263 | int vh_size; |
264 | |
265 | /* Buffer handling */ |
266 | struct vb2_queue vidq; |
267 | u32 sequence; |
268 | struct task_struct *kthread; |
269 | struct mutex lock; |
270 | spinlock_t slock; |
271 | int old_write; |
272 | struct list_head vidq_active; |
273 | }; |
274 | |
275 | static inline u32 solo_reg_read(struct solo_dev *solo_dev, int reg) |
276 | { |
277 | return readl(addr: solo_dev->reg_base + reg); |
278 | } |
279 | |
280 | static inline void solo_reg_write(struct solo_dev *solo_dev, int reg, |
281 | u32 data) |
282 | { |
283 | u16 val; |
284 | |
285 | writel(val: data, addr: solo_dev->reg_base + reg); |
286 | pci_read_config_word(dev: solo_dev->pdev, PCI_STATUS, val: &val); |
287 | } |
288 | |
289 | static inline void solo_irq_on(struct solo_dev *dev, u32 mask) |
290 | { |
291 | dev->irq_mask |= mask; |
292 | solo_reg_write(solo_dev: dev, SOLO_IRQ_MASK, data: dev->irq_mask); |
293 | } |
294 | |
295 | static inline void solo_irq_off(struct solo_dev *dev, u32 mask) |
296 | { |
297 | dev->irq_mask &= ~mask; |
298 | solo_reg_write(solo_dev: dev, SOLO_IRQ_MASK, data: dev->irq_mask); |
299 | } |
300 | |
301 | /* Init/exit routines for subsystems */ |
302 | int solo_disp_init(struct solo_dev *solo_dev); |
303 | void solo_disp_exit(struct solo_dev *solo_dev); |
304 | |
305 | int solo_gpio_init(struct solo_dev *solo_dev); |
306 | void solo_gpio_exit(struct solo_dev *solo_dev); |
307 | |
308 | int solo_i2c_init(struct solo_dev *solo_dev); |
309 | void solo_i2c_exit(struct solo_dev *solo_dev); |
310 | |
311 | int solo_p2m_init(struct solo_dev *solo_dev); |
312 | void solo_p2m_exit(struct solo_dev *solo_dev); |
313 | |
314 | int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr); |
315 | void solo_v4l2_exit(struct solo_dev *solo_dev); |
316 | |
317 | int solo_enc_init(struct solo_dev *solo_dev); |
318 | void solo_enc_exit(struct solo_dev *solo_dev); |
319 | |
320 | int solo_enc_v4l2_init(struct solo_dev *solo_dev, unsigned nr); |
321 | void solo_enc_v4l2_exit(struct solo_dev *solo_dev); |
322 | |
323 | int solo_g723_init(struct solo_dev *solo_dev); |
324 | void solo_g723_exit(struct solo_dev *solo_dev); |
325 | |
326 | /* ISR's */ |
327 | int solo_i2c_isr(struct solo_dev *solo_dev); |
328 | void solo_p2m_isr(struct solo_dev *solo_dev, int id); |
329 | void solo_p2m_error_isr(struct solo_dev *solo_dev); |
330 | void solo_enc_v4l2_isr(struct solo_dev *solo_dev); |
331 | void solo_g723_isr(struct solo_dev *solo_dev); |
332 | void solo_motion_isr(struct solo_dev *solo_dev); |
333 | void solo_video_in_isr(struct solo_dev *solo_dev); |
334 | |
335 | /* i2c read/write */ |
336 | u8 solo_i2c_readbyte(struct solo_dev *solo_dev, int id, u8 addr, u8 off); |
337 | void solo_i2c_writebyte(struct solo_dev *solo_dev, int id, u8 addr, u8 off, |
338 | u8 data); |
339 | |
340 | /* P2M DMA */ |
341 | int solo_p2m_dma_t(struct solo_dev *solo_dev, int wr, |
342 | dma_addr_t dma_addr, u32 ext_addr, u32 size, |
343 | int repeat, u32 ext_size); |
344 | int solo_p2m_dma(struct solo_dev *solo_dev, int wr, |
345 | void *sys_addr, u32 ext_addr, u32 size, |
346 | int repeat, u32 ext_size); |
347 | void solo_p2m_fill_desc(struct solo_p2m_desc *desc, int wr, |
348 | dma_addr_t dma_addr, u32 ext_addr, u32 size, |
349 | int repeat, u32 ext_size); |
350 | int solo_p2m_dma_desc(struct solo_dev *solo_dev, |
351 | struct solo_p2m_desc *desc, dma_addr_t desc_dma, |
352 | int desc_cnt); |
353 | |
354 | /* Global s_std ioctl */ |
355 | int solo_set_video_type(struct solo_dev *solo_dev, bool is_50hz); |
356 | void solo_update_mode(struct solo_enc_dev *solo_enc); |
357 | |
358 | /* Set the threshold for motion detection */ |
359 | int solo_set_motion_threshold(struct solo_dev *solo_dev, u8 ch, u16 val); |
360 | int solo_set_motion_block(struct solo_dev *solo_dev, u8 ch, |
361 | const u16 *thresholds); |
362 | #define SOLO_DEF_MOT_THRESH 0x0300 |
363 | |
364 | /* Write text on OSD */ |
365 | int solo_osd_print(struct solo_enc_dev *solo_enc); |
366 | |
367 | /* EEPROM commands */ |
368 | unsigned int solo_eeprom_ewen(struct solo_dev *solo_dev, int w_en); |
369 | __be16 solo_eeprom_read(struct solo_dev *solo_dev, int loc); |
370 | int solo_eeprom_write(struct solo_dev *solo_dev, int loc, |
371 | __be16 data); |
372 | |
373 | /* JPEG Qp functions */ |
374 | void solo_s_jpeg_qp(struct solo_dev *solo_dev, unsigned int ch, |
375 | unsigned int qp); |
376 | int solo_g_jpeg_qp(struct solo_dev *solo_dev, unsigned int ch); |
377 | |
378 | #define CHK_FLAGS(v, flags) (((v) & (flags)) == (flags)) |
379 | |
380 | #endif /* __SOLO6X10_H */ |
381 | |