├── driver ├── ntv2_hinreg.h ├── unload ├── ntv2_mixops.h ├── ntv2_v4l2ops.h ├── ntv2_vb2ops.h ├── ntv2_pcmops.h ├── load ├── ntv2_audioops.h ├── ntv2_device.h ├── ntv2_videoops.h ├── ntv2_hdmiedid.h ├── ntv2_chrdev.h ├── ntv2_serial.h ├── ntv2_pci.h ├── ntv2_konai2c.h ├── ntv2_register.h ├── ntv2_timecode.h ├── ntv2_input.h ├── ntv2_hdmiin4.h ├── ntv2_audio.h ├── ntv2_hdmiin.h ├── ntv2_video.h ├── ntv2_nwldma.h ├── ntv2_xlxdma.h ├── Makefile ├── ntv2_common.h ├── ntv2_mixops.c ├── ntv2_params.c ├── ntv2_register.c ├── ntv2_chrdev.c ├── ntv2_channel.h ├── ntv2_nwlreg.h ├── ntv2_driver.c ├── ntv2_xlxreg.h ├── ntv2_features.h ├── ntv2_pci.c ├── ntv2_timecode.c ├── ntv2_konai2c.c ├── ntv2_hdmiedid.c ├── ntv2_vb2ops.c ├── ntv2_params.h └── ntv2_audioops.c ├── .gitignore └── README.md /driver/ntv2_hinreg.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aja-video/ntv2-v4l2/HEAD/driver/ntv2_hinreg.h -------------------------------------------------------------------------------- /driver/unload: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | /sbin/rmmod ntv2video.ko 4 | 5 | # remove stale nodes 6 | rm -f /dev/ajantv2[0-3] 7 | rm -f /dev/oem2k[0-3] 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.ko 2 | *.ko.cmd 3 | *.mod.c 4 | *.o 5 | *.o.ur-safe 6 | *.o.cmd 7 | *.markers 8 | *.symvers 9 | *.order 10 | *# 11 | *~ 12 | .cache.mk 13 | .tmp_versions 14 | errors.txt 15 | semantic.cache 16 | TAGS 17 | tags 18 | -------------------------------------------------------------------------------- /driver/ntv2_mixops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 alsa mixer 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_MIXOPS_H 21 | #define NTV2_MIXOPS_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | int ntv2_mixops_capture_configure(struct ntv2_audio *ntv2_aud); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /driver/ntv2_v4l2ops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 v4l2 file ops 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_V4L2OPS_H 21 | #define NTV2_V4L2OPS_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | int ntv2_v4l2ops_configure(struct ntv2_video *ntv2_vid); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /driver/ntv2_vb2ops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 video buffer ops 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_VB2OPS_H 21 | #define NTV2_VB2OPS_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | int ntv2_vb2ops_configure(struct ntv2_video *ntv2_vid); 26 | 27 | struct ntv2_vb2buf *ntv2_vb2ops_vb2buf_ready(struct ntv2_video *ntv2_vid); 28 | void ntv2_vb2ops_vb2buf_done(struct ntv2_vb2buf *ntv2_buf); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /driver/ntv2_pcmops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 alsa pcm ops 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_PCMOPS_H 21 | #define NTV2_PCMOPS_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | int ntv2_pcmops_configure(struct ntv2_pcm_stream *stream); 26 | 27 | void ntv2_pcmops_tstamp(struct ntv2_pcm_stream *stream); 28 | 29 | void ntv2_pcmops_copy_audio(struct ntv2_pcm_stream *stream, 30 | u8 *address, 31 | u32 size, 32 | u32 num_channels, 33 | u32 sample_size); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /driver/load: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | find /lib/modules/$(uname -r) -name v4l2-common.ko -exec /sbin/modprobe v4l2-common \; 4 | find /lib/modules/$(uname -r) -name videobuf2-core.ko -exec /sbin/modprobe videobuf2-core \; 5 | find /lib/modules/$(uname -r) -name videobuf2-common.ko -exec /sbin/modprobe videobuf2-common \; 6 | find /lib/modules/$(uname -r) -name videobuf2-vmalloc.ko -exec /sbin/modprobe videobuf2-vmalloc \; 7 | find /lib/modules/$(uname -r) -name videobuf2-v4l2.ko -exec /sbin/modprobe videobuf2-v4l2 \; 8 | find /lib/modules/$(uname -r) -name snd.ko -exec /sbin/modprobe snd \; 9 | find /lib/modules/$(uname -r) -name snd-pcm.ko -exec /sbin/modprobe snd-pcm \; 10 | /sbin/rmmod ntv2video.ko && /sbin/insmod ntv2video.ko || /sbin/insmod ntv2video.ko 11 | 12 | # find ntv2dev major number 13 | major=`cat /proc/devices | awk "\\$2==\"ntv2dev\" {print \\$1}"` 14 | 15 | # remove and insert nodes 16 | rm -f /dev/ajantv2[0-3] 17 | mknod /dev/ajantv20 c $major 0 18 | mknod /dev/ajantv21 c $major 1 19 | mknod /dev/ajantv22 c $major 2 20 | mknod /dev/ajantv23 c $major 3 21 | 22 | chmod 666 /dev/ajantv2[0-3] 23 | 24 | rm -f /dev/oem2k[0-3] 25 | mknod /dev/oem2k0 c $major 0 26 | mknod /dev/oem2k1 c $major 1 27 | mknod /dev/oem2k2 c $major 2 28 | mknod /dev/oem2k3 c $major 3 29 | 30 | chmod 666 /dev/oem2k[0-3] 31 | -------------------------------------------------------------------------------- /driver/ntv2_audioops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 audio stream channel ops 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_AUDIOOPS_H 21 | #define NTV2_AUDIOOPS_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | struct ntv2_channel_stream; 26 | 27 | int ntv2_audioops_setup_capture(struct ntv2_channel_stream *stream); 28 | int ntv2_audioops_update_mode(struct ntv2_channel_stream *stream); 29 | int ntv2_audioops_update_route(struct ntv2_channel_stream *stream); 30 | int ntv2_audioops_interrupt_capture(struct ntv2_channel_stream *stream); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /driver/ntv2_device.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 device interface 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_DEVICE_H 21 | #define NTV2_DEVICE_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | struct ntv2_device *ntv2_device_open(struct ntv2_module *ntv2_mod, 26 | const char *name, int index); 27 | void ntv2_device_close(struct ntv2_device *ntv2_dev); 28 | 29 | int ntv2_device_configure(struct ntv2_device *ntv2_dev, struct pci_dev *pdev); 30 | 31 | void ntv2_device_suspend(struct ntv2_device *ntv2_dev); 32 | void ntv2_device_resume(struct ntv2_device *ntv2_dev); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /driver/ntv2_videoops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 video stream channel ops 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_VIDEOOPS_H 21 | #define NTV2_VIDEOOPS_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | struct ntv2_channel_stream; 26 | 27 | int ntv2_videoops_setup_capture(struct ntv2_channel_stream *stream); 28 | int ntv2_videoops_release_capture(struct ntv2_channel_stream *stream); 29 | int ntv2_videoops_update_mode(struct ntv2_channel_stream *stream); 30 | int ntv2_videoops_update_format(struct ntv2_channel_stream *stream); 31 | int ntv2_videoops_update_timing(struct ntv2_channel_stream *stream); 32 | int ntv2_videoops_update_route(struct ntv2_channel_stream *stream); 33 | int ntv2_videoops_update_frame(struct ntv2_channel_stream *stream); 34 | int ntv2_videoops_interrupt_capture(struct ntv2_channel_stream *stream); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /driver/ntv2_hdmiedid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 HDMI4 EDID 3 | * 4 | * Copyright 2018 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_HDMIEDID_H 21 | #define NTV2_HDMIEDID_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | #define NTV2_HDMI_EDID_SIZE 256 26 | 27 | 28 | struct ntv2_hdmiedid { 29 | int index; 30 | char name[NTV2_STRING_SIZE]; 31 | struct list_head list; 32 | struct ntv2_device *ntv2_dev; 33 | 34 | enum ntv2_edid_type edid_type; 35 | int port_index; 36 | 37 | u8 edid_data[NTV2_HDMI_EDID_SIZE]; 38 | u32 edid_size; 39 | }; 40 | 41 | 42 | struct ntv2_hdmiedid *ntv2_hdmiedid_open(struct ntv2_object *ntv2_obj, 43 | const char *name, int index); 44 | void ntv2_hdmiedid_close(struct ntv2_hdmiedid *ntv2_hed); 45 | 46 | int ntv2_hdmiedid_configure(struct ntv2_hdmiedid *ntv2_hed, 47 | enum ntv2_edid_type type, 48 | int port_index); 49 | 50 | u8 *ntv2_hdmi_get_edid_data(struct ntv2_hdmiedid *ntv2_hed); 51 | u32 ntv2_hdmi_get_edid_size(struct ntv2_hdmiedid *ntv2_hed); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /driver/ntv2_chrdev.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 character device interface 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_CHRDEV_H 21 | #define NTV2_CHRDEV_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | struct ntv2_features; 26 | 27 | struct ntv2_chrdev { 28 | int index; 29 | char name[NTV2_STRING_SIZE]; 30 | struct list_head list; 31 | struct ntv2_device *ntv2_dev; 32 | 33 | struct ntv2_features *features; 34 | struct ntv2_register *vid_reg; 35 | bool init; 36 | 37 | struct cdev cdev; 38 | spinlock_t state_lock; 39 | enum ntv2_task_state task_state; 40 | }; 41 | 42 | struct ntv2_chrdev *ntv2_chrdev_open(struct ntv2_object *ntv2_obj, 43 | const char *name, int index); 44 | void ntv2_chrdev_close(struct ntv2_chrdev *ntv2_chr); 45 | 46 | int ntv2_chrdev_configure(struct ntv2_chrdev *ntv2_chr, 47 | struct ntv2_features *features, 48 | struct ntv2_register *vid_reg); 49 | 50 | int ntv2_chrdev_enable(struct ntv2_chrdev *ntv2_chr); 51 | int ntv2_chrdev_disable(struct ntv2_chrdev *ntv2_chr); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /driver/ntv2_serial.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 serial device interface 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_SERIAL_H 21 | #define NTV2_SERIAL_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | struct ntv2_features; 26 | 27 | struct ntv2_serial { 28 | int index; 29 | char name[NTV2_STRING_SIZE]; 30 | struct list_head list; 31 | struct ntv2_device *ntv2_dev; 32 | 33 | struct ntv2_features *features; 34 | struct ntv2_register *vid_reg; 35 | 36 | bool uart_enable; 37 | spinlock_t state_lock; 38 | 39 | struct uart_port uart_port; 40 | bool busy; 41 | }; 42 | 43 | struct ntv2_serial *ntv2_serial_open(struct ntv2_object *ntv2_obj, 44 | const char *name, int index); 45 | void ntv2_serial_close(struct ntv2_serial *ntv2_ser); 46 | 47 | int ntv2_serial_configure(struct ntv2_serial *ntv2_ser, 48 | struct ntv2_features *features, 49 | struct ntv2_register *vid_reg); 50 | 51 | int ntv2_serial_enable(struct ntv2_serial *ntv2_ser); 52 | int ntv2_serial_disable(struct ntv2_serial *ntv2_ser); 53 | 54 | int ntv2_serial_interrupt(struct ntv2_serial *ntv2_ser, 55 | struct ntv2_interrupt_status* irq_status); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /driver/ntv2_pci.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 pci interface 3 | * 4 | * Copyright 2018 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_PCI_H 21 | #define NTV2_PCI_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | struct ntv2_nwldma; 26 | struct ntv2_xlxdma; 27 | 28 | struct ntv2_pci { 29 | int index; 30 | char name[NTV2_STRING_SIZE]; 31 | struct list_head list; 32 | struct ntv2_device *ntv2_dev; 33 | 34 | spinlock_t state_lock; 35 | enum ntv2_task_state pci_state; 36 | 37 | enum ntv2_pci_type pci_type; 38 | struct ntv2_register *pci_reg; 39 | 40 | struct ntv2_nwldma *nwl_engine[NTV2_MAX_DMA_ENGINES]; 41 | struct ntv2_xlxdma *xlx_engine[NTV2_MAX_DMA_ENGINES]; 42 | int num_engines; 43 | }; 44 | 45 | 46 | struct ntv2_pci *ntv2_pci_open(struct ntv2_object *ntv2_obj, 47 | const char *name, int index); 48 | void ntv2_pci_close(struct ntv2_pci *ntv2_pci); 49 | 50 | int ntv2_pci_configure(struct ntv2_pci *ntv2_pci, 51 | enum ntv2_pci_type pci_type, 52 | struct ntv2_register *pci_reg); 53 | 54 | int ntv2_pci_enable(struct ntv2_pci *ntv2_pci); 55 | int ntv2_pci_disable(struct ntv2_pci *ntv2_pci); 56 | 57 | int ntv2_pci_transfer(struct ntv2_pci *ntv2_pci, 58 | struct ntv2_transfer *ntv2_trn); 59 | 60 | int ntv2_pci_interrupt(struct ntv2_pci *ntv2_pci); 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /driver/ntv2_konai2c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 I2C register interface 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_KONAI2C_H 21 | #define NTV2_KONAI2C_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | struct ntv2_regsiter; 26 | 27 | struct ntv2_konai2c { 28 | int index; 29 | char name[NTV2_STRING_SIZE]; 30 | struct list_head list; 31 | struct ntv2_device *ntv2_dev; 32 | 33 | struct ntv2_register *kona_reg; 34 | u32 kona_control; 35 | u32 kona_data; 36 | u8 i2c_device; 37 | u32 reset_count; 38 | }; 39 | 40 | struct ntv2_konai2c *ntv2_konai2c_open(struct ntv2_object *ntv2_obj, 41 | const char *name, int index); 42 | void ntv2_konai2c_close(struct ntv2_konai2c *ntv2_i2c); 43 | 44 | int ntv2_konai2c_configure(struct ntv2_konai2c *ntv2_i2c, 45 | struct ntv2_register *ntv2_reg, 46 | u32 control, 47 | u32 data); 48 | 49 | void ntv2_konai2c_set_device(struct ntv2_konai2c *ntv2_i2c, u8 device); 50 | u8 ntv2_konai2c_get_device(struct ntv2_konai2c *ntv2_i2c); 51 | 52 | int ntv2_konai2c_write(struct ntv2_konai2c *ntv2_i2c, u8 address, u8 data); 53 | int ntv2_konai2c_cache_update(struct ntv2_konai2c *ntv2_i2c); 54 | u8 ntv2_konai2c_cache_read(struct ntv2_konai2c *ntv2_i2c, u8 address); 55 | int ntv2_konai2c_rmw(struct ntv2_konai2c *ntv2_i2c, u8 address, u8 data, u8 mask); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /driver/ntv2_register.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 PCI register interface 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_REGISTER_H 21 | #define NTV2_REGISTER_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | struct ntv2_register { 26 | int index; 27 | char name[NTV2_STRING_SIZE]; 28 | struct list_head list; 29 | struct ntv2_device *ntv2_dev; 30 | 31 | spinlock_t rmw_lock; 32 | void __iomem *base; 33 | u32 size; 34 | bool enable; 35 | }; 36 | 37 | struct ntv2_register *ntv2_register_open(struct ntv2_object *ntv2_obj, 38 | const char *name, int index); 39 | void ntv2_register_close(struct ntv2_register *ntv2_reg); 40 | 41 | int ntv2_register_configure(struct ntv2_register *ntv2_reg, 42 | void __iomem *base, 43 | u32 size); 44 | 45 | int ntv2_register_enable(struct ntv2_register *ntv2_reg); 46 | int ntv2_register_disable(struct ntv2_register *ntv2_reg); 47 | 48 | /* access by register number */ 49 | u32 ntv2_register_read(struct ntv2_register *ntv2_reg, u32 regnum); 50 | void ntv2_register_write(struct ntv2_register *ntv2_reg, u32 regnum, u32 data); 51 | u32 ntv2_register_rmw(struct ntv2_register *ntv2_reg, u32 regnum, u32 data, u32 mask); 52 | 53 | /* access by indexed register */ 54 | u32 ntv2_reg_read(struct ntv2_register *ntv2_reg, const u32 *reg, u32 index); 55 | void ntv2_reg_write(struct ntv2_register *ntv2_reg, const u32 *reg, u32 index, u32 data); 56 | u32 ntv2_reg_rmw(struct ntv2_register *ntv2_reg, const u32 *reg, u32 index, u32 data, u32 mask); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /driver/ntv2_timecode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 timecode utility 3 | * 4 | * Copyright 2018 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_TIMECODE_H 21 | #define NTV2_TIMECODE_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | struct ntv2_timecode_packed 26 | { 27 | u32 timecode_low; 28 | u32 timecode_high; 29 | }; 30 | 31 | struct ntv2_timecode_data 32 | { 33 | u32 hours; 34 | u32 minutes; 35 | u32 seconds; 36 | u32 frames; 37 | u32 user_bits; 38 | bool drop_frame; 39 | bool field; 40 | }; 41 | 42 | bool ntv2_timecode_compare_packed(struct ntv2_timecode_packed *tca, 43 | struct ntv2_timecode_packed *tcb, 44 | bool time_bits, bool user_bits); 45 | bool ntv2_timecode_compare_data(struct ntv2_timecode_data *tca, 46 | struct ntv2_timecode_data *tcb, 47 | bool time_bits, bool user_bits, bool field); 48 | 49 | void ntv2_timecode_copy_data(struct ntv2_timecode_data *dst, 50 | struct ntv2_timecode_data *src, 51 | bool time_bits, bool user_bits, bool field); 52 | 53 | void ntv2_timecode_unpack(struct ntv2_timecode_data *data, 54 | struct ntv2_timecode_packed *pack, 55 | u32 fps, bool field); 56 | void ntv2_timecode_pack(struct ntv2_timecode_data *data, 57 | struct ntv2_timecode_packed *pack, 58 | u32 fps, bool field); 59 | 60 | void ntv2_timecode_offset(struct ntv2_timecode_data *data, u32 fps, bool field, int count); 61 | void ntv2_timecode_increment(struct ntv2_timecode_data *data, u32 fps, bool field); 62 | void ntv2_timecode_decrement(struct ntv2_timecode_data *data, u32 fps, bool field); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /driver/ntv2_input.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 hardware input monitor 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_INPUT_H 21 | #define NTV2_INPUT_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | struct ntv2_features; 26 | struct ntv2_register; 27 | struct ntv2_input_config; 28 | struct ntv2_source_config; 29 | struct ntv2_hdmiin; 30 | struct ntv2_hdmiin4; 31 | 32 | struct ntv2_sdi_input_state { 33 | struct ntv2_sdi_input_status lock_status; 34 | struct ntv2_sdi_input_status last_status; 35 | int lock_count; 36 | int unlock_count; 37 | bool locked; 38 | bool changed; 39 | }; 40 | 41 | struct ntv2_input { 42 | int index; 43 | char name[NTV2_STRING_SIZE]; 44 | struct list_head list; 45 | struct ntv2_device *ntv2_dev; 46 | 47 | struct ntv2_features *features; 48 | struct ntv2_register *vid_reg; 49 | struct timer_list monitor_timer; 50 | spinlock_t state_lock; 51 | enum ntv2_task_state monitor_state; 52 | 53 | int num_sdi_inputs; 54 | int num_hdmi_inputs; 55 | int num_aes_inputs; 56 | 57 | int num_hdmi0_inputs; 58 | int num_hdmi4_inputs; 59 | 60 | struct ntv2_sdi_input_state sdi_input_state[NTV2_MAX_SDI_INPUTS]; 61 | struct ntv2_hdmiin *hdmi0_input[NTV2_MAX_HDMI_INPUTS]; 62 | struct ntv2_hdmiin4 *hdmi4_input[NTV2_MAX_HDMI_INPUTS]; 63 | }; 64 | 65 | struct ntv2_input *ntv2_input_open(struct ntv2_object *ntv2_obj, 66 | const char *name, int index); 67 | void ntv2_input_close(struct ntv2_input *ntv2_inp); 68 | 69 | int ntv2_input_configure(struct ntv2_input *ntv2_inp, 70 | struct ntv2_features *features, 71 | struct ntv2_register *vid_reg); 72 | 73 | int ntv2_input_enable(struct ntv2_input *ntv2_inp); 74 | int ntv2_input_disable(struct ntv2_input *ntv2_inp); 75 | 76 | int ntv2_input_set_timecode_dbb(struct ntv2_input *ntv2_inp, 77 | struct ntv2_input_config *config, 78 | u32 dbb); 79 | 80 | int ntv2_input_get_input_format(struct ntv2_input *ntv2_inp, 81 | struct ntv2_input_config *config, 82 | struct ntv2_input_format *format); 83 | 84 | int ntv2_input_get_source_format(struct ntv2_input *ntv2_inp, 85 | struct ntv2_source_config *config, 86 | struct ntv2_source_format *format); 87 | 88 | #endif 89 | 90 | -------------------------------------------------------------------------------- /driver/ntv2_hdmiin4.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 HDMI4 input control 3 | * 4 | * Copyright 2018 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_HDMIIN4_H 21 | #define NTV2_HDMIIN4_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | struct ntv2_features; 26 | struct ntv2_register; 27 | struct ntv2_input_config; 28 | struct ntv2_konai2c; 29 | struct ntv2_hdmiedid; 30 | 31 | #define NTV2_HDMIIN4_STRING_SIZE 80 32 | 33 | 34 | struct ntv2_hdmiin4_format { 35 | u32 video_standard; 36 | u32 frame_rate; 37 | u32 frame_flags; 38 | u32 pixel_flags; 39 | u32 audio_detect; 40 | }; 41 | 42 | struct ntv2_hdmiin4 { 43 | int index; 44 | char name[NTV2_STRING_SIZE]; 45 | struct list_head list; 46 | struct ntv2_device *ntv2_dev; 47 | 48 | struct ntv2_features *features; 49 | struct ntv2_register *vid_reg; 50 | struct ntv2_hdmiedid *edid; 51 | spinlock_t state_lock; 52 | 53 | struct ntv2_hdmiin4_format input_format; 54 | 55 | u32 video_control; 56 | u32 video_detect0; 57 | u32 video_detect1; 58 | u32 video_detect2; 59 | u32 video_detect3; 60 | u32 video_detect4; 61 | u32 video_detect5; 62 | u32 video_detect6; 63 | u32 video_detect7; 64 | u32 tmds_rate; 65 | 66 | bool input_locked; 67 | bool hdmi_mode; 68 | u32 video_standard; 69 | u32 frame_rate; 70 | u32 color_space; 71 | u32 color_depth; 72 | 73 | bool audio_swap; 74 | 75 | u32 format_clock_count; 76 | u32 format_raster_count; 77 | 78 | struct task_struct *monitor_task; 79 | enum ntv2_task_state monitor_state; 80 | }; 81 | 82 | struct ntv2_hdmiin4 *ntv2_hdmiin4_open(struct ntv2_object *ntv2_obj, 83 | const char *name, int index); 84 | void ntv2_hdmiin4_close(struct ntv2_hdmiin4 *ntv2_hin); 85 | 86 | int ntv2_hdmiin4_configure(struct ntv2_hdmiin4 *ntv2_hin, 87 | struct ntv2_features *features, 88 | struct ntv2_register *vid_reg, 89 | int port_index); 90 | 91 | int ntv2_hdmiin4_enable(struct ntv2_hdmiin4 *ntv2_hin); 92 | int ntv2_hdmiin4_disable(struct ntv2_hdmiin4 *ntv2_hin); 93 | 94 | int ntv2_hdmiin4_get_input_format(struct ntv2_hdmiin4 *ntv2_hin, 95 | struct ntv2_hdmiin4_format *format); 96 | 97 | int ntv2_hdmiin4_periodic_update(struct ntv2_hdmiin4 *ntv2_hin); 98 | 99 | #endif 100 | 101 | -------------------------------------------------------------------------------- /driver/ntv2_audio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 alsa device interface 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_AUDIO_H 21 | #define NTV2_AUDIO_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | #define NTV2_PCM_DMA_BUFFER_SIZE 4800*16*4 26 | 27 | struct ntv2_audio; 28 | struct ntv2_features; 29 | struct ntv2_pci; 30 | struct ntv2_source_config; 31 | 32 | struct ntv2_pcm_stream { 33 | enum ntv2_stream_type type; 34 | struct ntv2_audio *ntv2_aud; 35 | spinlock_t state_lock; 36 | struct tasklet_struct transfer_task; 37 | enum ntv2_task_state transfer_state; 38 | enum ntv2_task_state task_state; 39 | 40 | struct ntv2_channel_stream *chn_str; 41 | struct snd_pcm_substream *substream; 42 | u32 sample_ptr; 43 | u32 period_ptr; 44 | u32 sample_cycle; 45 | bool trigger; 46 | 47 | struct ntv2_stream_data *dma_audbuf; 48 | bool dma_start; 49 | bool dma_done; 50 | int dma_result; 51 | u32 dma_size; 52 | 53 | u8 *dma_buffer; 54 | u32 dma_buffer_size; 55 | struct sg_table dma_sgtable; 56 | u32 dma_buffer_pages; 57 | }; 58 | 59 | struct ntv2_audio { 60 | int index; 61 | char name[NTV2_STRING_SIZE]; 62 | struct list_head list; 63 | struct ntv2_device *ntv2_dev; 64 | 65 | struct ntv2_features *features; 66 | struct snd_card *snd_card; 67 | struct ntv2_channel *ntv2_chn; 68 | struct ntv2_input *ntv2_inp; 69 | struct ntv2_pci *ntv2_pci; 70 | bool init; 71 | 72 | u32 snd_input; 73 | 74 | struct ntv2_source_format source_format; 75 | 76 | struct snd_pcm *pcm; 77 | struct ntv2_pcm_stream *capture; 78 | struct ntv2_pcm_stream *playback; 79 | }; 80 | 81 | struct ntv2_audio *ntv2_audio_open(struct ntv2_object *ntv2_obj, 82 | const char *name, int index); 83 | void ntv2_audio_close(struct ntv2_audio *ntv2_aud); 84 | 85 | void ntv2_audio_disable_all(struct ntv2_audio *ntv2_aud); 86 | 87 | int ntv2_audio_configure(struct ntv2_audio *ntv2_aud, 88 | struct ntv2_features *features, 89 | struct snd_card *snd_card, 90 | struct ntv2_channel *ntv2_chn, 91 | struct ntv2_input *ntv2_inp, 92 | struct ntv2_pci *ntv2_pci); 93 | 94 | int ntv2_audio_set_source(struct ntv2_audio *ntv2_aud, 95 | struct ntv2_source_config *config); 96 | 97 | struct ntv2_pcm_stream *ntv2_audio_capture_stream(struct ntv2_audio *ntv2_aud); 98 | struct ntv2_pcm_stream *ntv2_audio_playback_stream(struct ntv2_audio *ntv2_aud); 99 | 100 | int ntv2_audio_enable(struct ntv2_pcm_stream *stream); 101 | int ntv2_audio_disable(struct ntv2_pcm_stream *stream); 102 | 103 | int ntv2_audio_start(struct ntv2_pcm_stream *stream); 104 | int ntv2_audio_stop(struct ntv2_pcm_stream *stream); 105 | int ntv2_audio_flush(struct ntv2_pcm_stream *stream); 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /driver/ntv2_hdmiin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 HDMI input control 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_HDMIIN_H 21 | #define NTV2_HDMIIN_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | struct ntv2_features; 26 | struct ntv2_register; 27 | struct ntv2_input_config; 28 | struct ntv2_konai2c; 29 | struct ntv2_hdmiedid; 30 | 31 | struct ntv2_hdmiin_format { 32 | u32 video_standard; 33 | u32 frame_rate; 34 | u32 frame_flags; 35 | u32 pixel_flags; 36 | u32 audio_detect; 37 | }; 38 | 39 | struct ntv2_hdmiin { 40 | int index; 41 | char name[NTV2_STRING_SIZE]; 42 | struct list_head list; 43 | struct ntv2_device *ntv2_dev; 44 | 45 | struct ntv2_features *features; 46 | struct ntv2_register *vid_reg; 47 | struct ntv2_konai2c *i2c_reg; 48 | struct ntv2_hdmiedid *edid; 49 | spinlock_t state_lock; 50 | 51 | u8 i2c_hpa_default; 52 | u8 i2c_color_default; 53 | u32 i2c_reset_count; 54 | u32 lock_error_count; 55 | 56 | struct ntv2_hdmiin_format input_format; 57 | 58 | u32 relock_reports; 59 | bool hdmi_mode; 60 | bool hdcp_mode; 61 | bool derep_mode; 62 | bool uhd_mode; 63 | bool interlaced_mode; 64 | bool pixel_double_mode; 65 | bool yuv_mode; 66 | bool deep_color_10bit; 67 | bool deep_color_12bit; 68 | bool audio_multichannel; 69 | bool prefer_yuv; 70 | bool prefer_rgb; 71 | 72 | bool cable_present; 73 | bool clock_present; 74 | bool input_locked; 75 | bool audio_present; 76 | bool audio_locked; 77 | bool avi_packet_present; 78 | bool vsi_packet_present; 79 | 80 | u32 h_active_pixels; 81 | u32 h_total_pixels; 82 | u32 h_front_porch_pixels; 83 | u32 h_sync_pixels; 84 | u32 h_back_porch_pixels; 85 | u32 v_total_lines0; 86 | u32 v_total_lines1; 87 | u32 v_active_lines0; 88 | u32 v_active_lines1; 89 | u32 v_sync_lines0; 90 | u32 v_sync_lines1; 91 | u32 v_front_porch_lines0; 92 | u32 v_front_porch_lines1; 93 | u32 v_back_porch_lines0; 94 | u32 v_back_porch_lines1; 95 | u32 v_frequency; 96 | u32 tmds_frequency; 97 | 98 | u32 color_space; 99 | u32 color_depth; 100 | 101 | struct task_struct *monitor_task; 102 | enum ntv2_task_state monitor_state; 103 | }; 104 | 105 | struct ntv2_hdmiin *ntv2_hdmiin_open(struct ntv2_object *ntv2_obj, 106 | const char *name, int index); 107 | void ntv2_hdmiin_close(struct ntv2_hdmiin *ntv2_hin); 108 | 109 | int ntv2_hdmiin_configure(struct ntv2_hdmiin *ntv2_hin, 110 | struct ntv2_features *features, 111 | struct ntv2_register *vid_reg, 112 | int port_index); 113 | 114 | int ntv2_hdmiin_enable(struct ntv2_hdmiin *ntv2_hin); 115 | int ntv2_hdmiin_disable(struct ntv2_hdmiin *ntv2_hin); 116 | 117 | int ntv2_hdmiin_get_input_format(struct ntv2_hdmiin *ntv2_hin, 118 | struct ntv2_hdmiin_format *format); 119 | 120 | int ntv2_hdmiin_periodic_update(struct ntv2_hdmiin *ntv2_hin); 121 | 122 | #endif 123 | 124 | -------------------------------------------------------------------------------- /driver/ntv2_video.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 v4l2 device interface 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_VIDEO_H 21 | #define NTV2_VIDEO_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | struct ntv2_features; 26 | struct ntv2_pci; 27 | 28 | struct ntv2_vb2buf { 29 | #ifdef NTV2_USE_VB2_V4L2_BUFFER 30 | struct vb2_v4l2_buffer vb2_v4l2_buffer; 31 | #else 32 | struct vb2_buffer vb2_buffer; /* must be first */ 33 | #endif 34 | int index; 35 | struct list_head list; 36 | struct ntv2_video *ntv2_vid; 37 | 38 | bool init; 39 | struct sg_table *sgtable; 40 | struct sg_table vmalloc_table; 41 | int num_pages; 42 | }; 43 | 44 | struct ntv2_video { 45 | int index; 46 | char name[NTV2_STRING_SIZE]; 47 | struct list_head list; 48 | struct ntv2_device *ntv2_dev; 49 | 50 | struct ntv2_features *features; 51 | struct ntv2_channel *ntv2_chn; 52 | struct ntv2_input *ntv2_inp; 53 | struct ntv2_pci *ntv2_pci; 54 | bool init; 55 | 56 | struct ntv2_channel_stream *vid_str; 57 | struct ntv2_channel_stream *aud_str; 58 | struct v4l2_device v4l2_dev; 59 | struct v4l2_ctrl_handler ctrl_handler; 60 | struct video_device video_dev; 61 | struct mutex video_mutex; 62 | bool v4l2_init; 63 | bool ctrl_init; 64 | bool video_init; 65 | spinlock_t state_lock; 66 | struct tasklet_struct transfer_task; 67 | enum ntv2_task_state transfer_state; 68 | enum ntv2_task_state task_state; 69 | atomic_t video_ref; 70 | 71 | v4l2_std_id v4l2_std; 72 | struct v4l2_dv_timings v4l2_timings; 73 | struct v4l2_pix_format v4l2_format; 74 | u32 v4l2_input; 75 | 76 | struct ntv2_pixel_format pixel_format; 77 | struct ntv2_video_format video_format; 78 | struct ntv2_input_format input_format; 79 | bool drop_frame; 80 | 81 | struct vb2_queue vb2_queue; 82 | struct mutex vb2_mutex; 83 | spinlock_t vb2_lock; 84 | bool vb2_init; 85 | bool vb2_start; 86 | 87 | struct list_head vb2buf_list; 88 | int vb2buf_index; 89 | u64 vb2buf_sequence; 90 | 91 | struct ntv2_vb2buf *dma_vb2buf; 92 | struct ntv2_stream_data *dma_vidbuf; 93 | bool dma_start; 94 | bool dma_done; 95 | int dma_result; 96 | bool input_changed; 97 | }; 98 | 99 | struct ntv2_video *ntv2_video_open(struct ntv2_object *ntv2_obj, 100 | const char *name, int index); 101 | void ntv2_video_close(struct ntv2_video *ntv2_vid); 102 | 103 | int ntv2_video_configure(struct ntv2_video *ntv2_vid, 104 | struct ntv2_features *features, 105 | struct ntv2_channel *ntv2_chn, 106 | struct ntv2_input *ntv2_inp, 107 | struct ntv2_pci *ntv2_pci); 108 | 109 | void ntv2_video_update(struct ntv2_video *ntv2_vid); 110 | 111 | int ntv2_video_enable(struct ntv2_video *ntv2_vid); 112 | int ntv2_video_disable(struct ntv2_video *ntv2_vid); 113 | 114 | int ntv2_video_start(struct ntv2_video *ntv2_vid); 115 | int ntv2_video_stop(struct ntv2_video *ntv2_vid); 116 | int ntv2_video_flush(struct ntv2_video *ntv2_vid); 117 | 118 | bool ntv2_video_compatible_input_format(struct ntv2_input_format *inpf, 119 | struct ntv2_video_format *vidf); 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /driver/ntv2_nwldma.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 Northwest Logic DMA interface 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_NWLDMA_H 21 | #define NTV2_NWLDMA_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | #define NTV2_NWLDMA_MAX_TASKS 64 26 | 27 | enum ntv2_nwldma_state { 28 | ntv2_nwldma_state_unknown, 29 | ntv2_nwldma_state_idle, 30 | ntv2_nwldma_state_start, 31 | ntv2_nwldma_state_transfer, 32 | ntv2_nwldma_state_done, 33 | ntv2_nwldma_state_timeout, 34 | ntv2_nwldma_state_abort, 35 | ntv2_nwldma_state_size 36 | }; 37 | 38 | /* nwl dma descriptor */ 39 | struct ntv2_nwldma_descriptor { 40 | u32 control; 41 | u32 byte_count; 42 | u64 system_address; 43 | u64 card_address; 44 | u64 next_address; 45 | }; 46 | 47 | struct ntv2_nwldma_task { 48 | int index; 49 | struct list_head list; 50 | struct ntv2_nwldma *ntv2_nwl; 51 | 52 | enum ntv2_transfer_mode mode; 53 | struct scatterlist *sg_list; 54 | u32 sg_pages; 55 | u32 sg_offset; 56 | u32 card_address[2]; 57 | u32 card_size[2]; 58 | 59 | ntv2_transfer_callback callback_func; 60 | unsigned long callback_data; 61 | 62 | bool dma_start; 63 | bool dma_done; 64 | int dma_result; 65 | }; 66 | 67 | struct ntv2_nwldma { 68 | int index; 69 | char name[NTV2_STRING_SIZE]; 70 | struct list_head list; 71 | struct ntv2_device *ntv2_dev; 72 | 73 | struct ntv2_register *nwl_reg; 74 | 75 | struct tasklet_struct engine_task; 76 | struct tasklet_struct engine_dpc; 77 | struct timer_list engine_timer; 78 | enum ntv2_nwldma_state engine_state; 79 | 80 | spinlock_t state_lock; 81 | enum ntv2_task_state dma_state; 82 | enum ntv2_task_state task_state; 83 | 84 | enum ntv2_transfer_mode mode; 85 | u32 engine_number; 86 | u32 card_address_size; 87 | u32 max_transfer_size; 88 | u32 max_pages; 89 | u32 max_descriptors; 90 | 91 | struct ntv2_nwldma_descriptor *descriptor; 92 | dma_addr_t dma_descriptor; 93 | size_t descriptor_memsize; 94 | 95 | struct ntv2_nwldma_task *dma_task; 96 | u32 dpc_control_status; 97 | u32 descriptor_bytes; 98 | u32 descriptor_count; 99 | 100 | s64 transfer_start_count; 101 | s64 transfer_complete_count; 102 | s64 interrupt_count; 103 | s64 dpc_count; 104 | s64 error_count; 105 | 106 | s64 soft_transfer_time_start; 107 | s64 soft_dma_time_start; 108 | 109 | s64 stat_transfer_count; 110 | s64 stat_transfer_bytes; 111 | s64 stat_transfer_time; 112 | s64 stat_descriptor_count; 113 | s64 soft_transfer_time; 114 | s64 soft_dma_time; 115 | s64 stat_last_display_time; 116 | 117 | struct ntv2_nwldma_task dmatask_array[NTV2_NWLDMA_MAX_TASKS]; 118 | 119 | struct list_head dmatask_ready_list; 120 | struct list_head dmatask_done_list; 121 | }; 122 | 123 | struct ntv2_nwldma *ntv2_nwldma_open(struct ntv2_object *ntv2_obj, 124 | const char *name, int index); 125 | void ntv2_nwldma_close(struct ntv2_nwldma *ntv2_nwl); 126 | 127 | int ntv2_nwldma_configure(struct ntv2_nwldma *ntv2_nwl, struct ntv2_register *nwl_reg); 128 | 129 | int ntv2_nwldma_enable(struct ntv2_nwldma *ntv2_nwl); 130 | int ntv2_nwldma_disable(struct ntv2_nwldma *ntv2_nwl); 131 | 132 | int ntv2_nwldma_transfer(struct ntv2_nwldma *ntv2_nwl, 133 | struct ntv2_transfer* ntv2_trn); 134 | 135 | int ntv2_nwldma_interrupt(struct ntv2_nwldma *ntv2_nwl); 136 | void ntv2_nwldma_abort(struct ntv2_nwldma *ntv2_nwl); 137 | 138 | void ntv2_nwldma_interrupt_enable(struct ntv2_register *nwl_reg); 139 | void ntv2_nwldma_interrupt_disable(struct ntv2_register *nwl_reg); 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /driver/ntv2_xlxdma.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 Xilinx DMA interface 3 | * 4 | * Copyright 2018 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_XLXDMA_H 21 | #define NTV2_XLXDMA_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | #define NTV2_XLXDMA_MAX_TASKS 64 26 | 27 | enum ntv2_xlxdma_state { 28 | ntv2_xlxdma_state_unknown, 29 | ntv2_xlxdma_state_idle, 30 | ntv2_xlxdma_state_start, 31 | ntv2_xlxdma_state_transfer, 32 | ntv2_xlxdma_state_done, 33 | ntv2_xlxdma_state_timeout, 34 | ntv2_xlxdma_state_abort, 35 | ntv2_xlxdma_state_size 36 | }; 37 | 38 | /* xlx dma descriptor */ 39 | struct ntv2_xlxdma_descriptor { 40 | u32 control; 41 | u32 byte_count; 42 | u64 src_address; 43 | u64 dst_address; 44 | u64 nxt_address; 45 | }; 46 | 47 | struct ntv2_xlxdma_task { 48 | int index; 49 | struct list_head list; 50 | struct ntv2_xlxdma *ntv2_xlx; 51 | 52 | enum ntv2_transfer_mode mode; 53 | struct scatterlist *sg_list; 54 | u32 sg_pages; 55 | u32 sg_offset; 56 | u32 card_address[2]; 57 | u32 card_size[2]; 58 | 59 | ntv2_transfer_callback callback_func; 60 | unsigned long callback_data; 61 | 62 | bool dma_start; 63 | bool dma_done; 64 | int dma_result; 65 | }; 66 | 67 | struct ntv2_xlxdma { 68 | int index; 69 | char name[NTV2_STRING_SIZE]; 70 | struct list_head list; 71 | struct ntv2_device *ntv2_dev; 72 | 73 | struct ntv2_register *xlx_reg; 74 | 75 | struct tasklet_struct engine_task; 76 | struct tasklet_struct engine_dpc; 77 | struct timer_list engine_timer; 78 | enum ntv2_xlxdma_state engine_state; 79 | 80 | spinlock_t state_lock; 81 | enum ntv2_task_state dma_state; 82 | enum ntv2_task_state task_state; 83 | 84 | u32 s2c_channels; 85 | u32 c2s_channels; 86 | enum ntv2_transfer_mode mode; 87 | u32 engine_number; 88 | u32 interrupt_mask; 89 | u32 card_address_size; 90 | u32 max_transfer_size; 91 | u32 max_pages; 92 | u32 max_descriptors; 93 | 94 | struct ntv2_xlxdma_descriptor *descriptor; 95 | dma_addr_t dma_descriptor; 96 | size_t descriptor_memsize; 97 | 98 | struct ntv2_xlxdma_task *dma_task; 99 | u32 descriptor_bytes; 100 | u32 descriptor_count; 101 | 102 | s64 transfer_start_count; 103 | s64 transfer_complete_count; 104 | s64 interrupt_count; 105 | s64 dpc_count; 106 | s64 error_count; 107 | 108 | s64 soft_transfer_time_start; 109 | s64 soft_dma_time_start; 110 | 111 | s64 stat_transfer_count; 112 | s64 stat_transfer_bytes; 113 | s64 stat_transfer_time; 114 | s64 stat_descriptor_count; 115 | s64 soft_transfer_time; 116 | s64 soft_dma_time; 117 | s64 stat_last_display_time; 118 | 119 | struct ntv2_xlxdma_task dmatask_array[NTV2_XLXDMA_MAX_TASKS]; 120 | 121 | struct list_head dmatask_ready_list; 122 | struct list_head dmatask_done_list; 123 | }; 124 | 125 | struct ntv2_xlxdma *ntv2_xlxdma_open(struct ntv2_object *ntv2_obj, 126 | const char *name, int index); 127 | void ntv2_xlxdma_close(struct ntv2_xlxdma *ntv2_xlx); 128 | 129 | int ntv2_xlxdma_configure(struct ntv2_xlxdma *ntv2_xlx, struct ntv2_register *xlx_reg); 130 | 131 | int ntv2_xlxdma_enable(struct ntv2_xlxdma *ntv2_xlx); 132 | int ntv2_xlxdma_disable(struct ntv2_xlxdma *ntv2_xlx); 133 | 134 | int ntv2_xlxdma_transfer(struct ntv2_xlxdma *ntv2_xlx, 135 | struct ntv2_transfer* ntv2_trn); 136 | 137 | int ntv2_xlxdma_interrupt(struct ntv2_xlxdma *ntv2_xlx); 138 | void ntv2_xlxdma_abort(struct ntv2_xlxdma *ntv2_xlx); 139 | 140 | void ntv2_xlxdma_interrupt_enable(struct ntv2_register *xlx_reg); 141 | void ntv2_xlxdma_interrupt_disable(struct ntv2_register *xlx_reg); 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /driver/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # NTV2 v4l2 driver makefile 3 | # 4 | # Copyright (C) 2016 AJA Video Systems, Inc. 5 | # 6 | 7 | USER = $(shell whoami) 8 | PWD = $(shell pwd) 9 | CPU_ARCH ?= $(shell uname -m) 10 | LINUX_DISTRO ?= GENERIC 11 | DRIVERDIR ?= $(PWD) 12 | KDIR ?= /lib/modules/$(shell uname -r)/build 13 | CC = gcc 14 | DRIVERNAME = ntv2video 15 | 16 | DRIVERTARGET = $(DRIVERNAME).o 17 | INCLUDES = -I. -I$(DRIVERDIR) 18 | ARCH_CFLAGS ?= -D$(LINUX_DISTRO) -D$(CPU_ARCH) 19 | EXTRA_CFLAGS += $(ARCH_CFLAGS) $(INCLUDES) -Wall -Wno-unused-function 20 | LDFLAGS := 21 | export LDFLAGS 22 | 23 | DRIVERSRCS = ntv2_driver.c \ 24 | ntv2_params.c \ 25 | ntv2_device.c \ 26 | ntv2_video.c \ 27 | ntv2_vb2ops.c \ 28 | ntv2_v4l2ops.c \ 29 | ntv2_audio.c \ 30 | ntv2_pcmops.c \ 31 | ntv2_channel.c \ 32 | ntv2_register.c \ 33 | ntv2_pci.c \ 34 | ntv2_nwldma.c \ 35 | ntv2_xlxdma.c \ 36 | ntv2_konareg.c \ 37 | ntv2_timecode.c \ 38 | ntv2_features.c \ 39 | ntv2_videoops.c \ 40 | ntv2_audioops.c \ 41 | ntv2_input.c \ 42 | ntv2_konai2c.c \ 43 | ntv2_hdmiin.c \ 44 | ntv2_hdmiin4.c \ 45 | ntv2_hdmiedid.c \ 46 | ntv2_serial.c \ 47 | ntv2_mixops.c \ 48 | ntv2_chrdev.c 49 | 50 | DRIVEROBJS = $(patsubst %.c,%.o,$(DRIVERSRCS)) 51 | 52 | DRIVERINCS = ntv2_common.h \ 53 | ntv2_params.h \ 54 | ntv2_device.h \ 55 | ntv2_video.h \ 56 | ntv2_vb2ops.h \ 57 | ntv2_v4l2ops.h \ 58 | ntv2_audio.h \ 59 | ntv2_pcmops.h \ 60 | ntv2_channel.h \ 61 | ntv2_register.h \ 62 | ntv2_pci.h \ 63 | ntv2_nwldma.h \ 64 | ntv2_nwlreg.h \ 65 | ntv2_xlxdma.h \ 66 | ntv2_xlxreg.h \ 67 | ntv2_konareg.h \ 68 | ntv2_timecode.h \ 69 | ntv2_features.h \ 70 | ntv2_videoops.h \ 71 | ntv2_audioops.h \ 72 | ntv2_input.h \ 73 | ntv2_konai2c.h \ 74 | ntv2_hdmiin.h \ 75 | ntv2_hdmiin4.h \ 76 | ntv2_hdmiedid.h \ 77 | ntv2_hinreg.h \ 78 | ntv2_serial.h \ 79 | ntv2_mixops.h \ 80 | ntv2_chrdev.h 81 | 82 | obj-m := $(DRIVERTARGET) 83 | $(DRIVERNAME)-y := $(DRIVEROBJS) 84 | 85 | .PHONY: default 86 | default: all 87 | $(MAKE) -C $(KDIR) M=$(DRIVERDIR) DRIVERDIR=$(DRIVERDIR) modules 88 | 89 | .PHONY: all 90 | all: $(DRIVERSRCS) $(DRIVERINCS) 91 | 92 | .PHONY: load 93 | load: mod var nod 94 | 95 | # Load kernel modules 96 | .PHONY: mod 97 | mod: 98 | @if [ $$USER != 'root' ]; then echo "Load requires elevated privileges (try again with sudo?)" && exit 127;fi 99 | find /lib/modules/$(shell uname -r) -name v4l2-common.ko -exec /sbin/modprobe v4l2-common \; 100 | find /lib/modules/$(shell uname -r) -name videobuf2-core.ko -exec /sbin/modprobe videobuf2-core \; 101 | find /lib/modules/$(shell uname -r) -name videobuf2-common.ko -exec /sbin/modprobe videobuf2-common \; 102 | find /lib/modules/$(shell uname -r) -name videobuf2-vmalloc.ko -exec /sbin/modprobe videobuf2-vmalloc \; 103 | find /lib/modules/$(shell uname -r) -name videobuf2-v4l2.ko -exec /sbin/modprobe videobuf2-v4l2 \; 104 | find /lib/modules/$(shell uname -r) -name snd.ko -exec /sbin/modprobe snd \; 105 | find /lib/modules/$(shell uname -r) -name snd-pcm.ko -exec /sbin/modprobe snd-pcm \; 106 | /sbin/rmmod ntv2video.ko && /sbin/insmod ntv2video.ko || /sbin/insmod ntv2video.ko 107 | 108 | # find ntv2dev major number 109 | .PHONY: var 110 | var: 111 | $(eval MAJOR = $(shell cat /proc/devices | awk '$$2=="ntv2dev" {print $$1}')) 112 | 113 | # remove and insert nodes 114 | .PHONY: nod 115 | nod: 116 | rm -f /dev/ajantv2[0-3] 117 | mknod /dev/ajantv20 c $(MAJOR) 0 118 | mknod /dev/ajantv21 c $(MAJOR) 1 119 | mknod /dev/ajantv22 c $(MAJOR) 2 120 | mknod /dev/ajantv23 c $(MAJOR) 3 121 | chmod 666 /dev/ajantv2[0-3] 122 | rm -f /dev/oem2k[0-3] 123 | mknod /dev/oem2k0 c $(MAJOR) 0 124 | mknod /dev/oem2k1 c $(MAJOR) 1 125 | mknod /dev/oem2k2 c $(MAJOR) 2 126 | mknod /dev/oem2k3 c $(MAJOR) 3 127 | chmod 666 /dev/oem2k[0-3] 128 | @echo "Load complete!" 129 | 130 | .PHONY: unload 131 | unload: 132 | @if [ $$USER != 'root' ]; then echo "Unload requires elevated privileges (try again with sudo?)" && exit 127;fi 133 | /sbin/rmmod ntv2video.ko 134 | rm -f /dev/ajantv2[0-3] 135 | rm -f /dev/oem2k[0-3] 136 | @echo "Unload complete!" 137 | 138 | .PHONY: clean 139 | clean: 140 | rm -f *.ko *.o .*o.cmd *.o.ur-safe *.mod.c *~ errors.txt semantic.cache 141 | rm -rf .tmp_versions 142 | rm -f *.markers *.symvers *.order .cache.mk 143 | 144 | .PHONY: cleandeps 145 | cleandeps: clean 146 | 147 | .PHONY: realclean 148 | realclean: clean 149 | 150 | -------------------------------------------------------------------------------- /driver/ntv2_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 v4l2 driver common header 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_COMMON_H 21 | #define NTV2_COMMON_H 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #define GSPCA_DEBUG 46 | 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | 58 | /* 59 | build pararameters for approximate ubuntu kernel versions 60 | */ 61 | 62 | /* 3.10.0 does build */ 63 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)) 64 | #define NTV2_USE_VB2_VOID_FINISH /* 3.15.0 required */ 65 | #define NTV2_USE_VB2_TIMESTAMP_FLAGS /* 3.15.0 required */ 66 | #endif 67 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0)) 68 | #define NTV2_USE_VB2_VOID_STREAMING /* 3.16.0 required */ 69 | #define NTV2_USE_SND_CARD_NEW /* 3.16.0 required */ 70 | #define NTV2_ZERO_ENUM_TIMINGS_PAD /* 3.16.0 optional */ 71 | #define NTV2_USE_V4L2_EVENT /* 3.16.0 optional */ 72 | #endif 73 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)) 74 | #define NTV2_USE_V4L2_FH /* 3.17.0 required */ 75 | #define NTV2_USE_TTY_GROUP /* 3.17.0 required */ 76 | #define NTV2_RGB_PIXEL_FORMATS /* 3.17.0 required */ 77 | #endif 78 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) 79 | #define NTV2_USE_VB2_V4L2_BUFFER /* 4.4.0 required */ 80 | #define NTV2_USE_QUEUE_SETUP_PARG /* 4.4.0 required */ 81 | #endif 82 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) 83 | #define NTV2_USE_VB2_BUFFER_TIMESTAMP /* 4.5.0 required */ 84 | #define NTV2_USE_QUEUE_SETUP_NO_FORMAT /* 4.5.0 required */ 85 | #endif 86 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0)) 87 | #define NTV2_USE_QUEUE_SETUP_DEVICE /* 4.8.0 required */ 88 | #endif 89 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,15,0)) 90 | #define NTV2_USE_TIMER_SETUP /* 4.15.0 required */ 91 | #endif 92 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0)) 93 | #define NTV2_USE_KTIME /* 5.0.0 required */ 94 | #define NTV2_USE_PIXEL_ASPECT /* 5.0.0 required */ 95 | #define NTV2_USE_PCI_CHANNEL_STATE_T 96 | #endif 97 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,4,0)) 98 | #define NTV2_VIDEO_DEVICE_CAPABILITES /* 5.4.0 required */ 99 | #endif 100 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,4,0)) 101 | #define NTV2_USE_IOREMAP /* 5.6.0 required */ 102 | #endif 103 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,7,0)) 104 | #define NTV2_USE_VFL_TYPE_VIDEO /* 5.7.0 required */ 105 | #endif 106 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)) 107 | #define NTV2_USE_TERMIOS_CONST 108 | #endif 109 | /* 5.0.0 does build */ 110 | 111 | /* 112 | build pararameter for Centos 7 or any system with a pre 3.16 113 | kernel that crashes on driver load 114 | */ 115 | //#define NTV2_USE_SND_CARD_NEW 116 | 117 | #ifdef NTV2_USE_VB2_V4L2_BUFFER 118 | #include 119 | #endif 120 | 121 | /* 122 | use dma sg for slight improvement in dma performance 123 | but does not work in all kernels 124 | */ 125 | //#define NTV2_USE_VB2_DMA_SG 126 | 127 | #include "ntv2_params.h" 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /driver/ntv2_mixops.c: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 alsa mixer 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #include "ntv2_audio.h" 21 | #include "ntv2_features.h" 22 | #include "ntv2_mixops.h" 23 | #include "ntv2_channel.h" 24 | 25 | 26 | static int ntv2_mixops_info_source_control(struct snd_kcontrol *kcontrol, 27 | struct snd_ctl_elem_info *info) 28 | { 29 | struct ntv2_audio *ntv2_aud = (struct ntv2_audio *)snd_kcontrol_chip(kcontrol); 30 | struct ntv2_features *features; 31 | struct ntv2_source_config *config; 32 | u32 num_sources; 33 | 34 | features = ntv2_aud->features; 35 | num_sources = ntv2_features_num_source_configs(ntv2_aud->features, ntv2_aud->ntv2_chn->index); 36 | 37 | info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 38 | info->count = 1; 39 | info->value.enumerated.items = num_sources; 40 | 41 | if (info->value.enumerated.item >= num_sources) 42 | info->value.enumerated.item = num_sources - 1; 43 | 44 | config = ntv2_features_get_source_config(features, 45 | ntv2_aud->ntv2_chn->index, 46 | info->value.enumerated.item); 47 | 48 | if (config != NULL) { 49 | strlcpy(info->value.enumerated.name, config->name, sizeof(info->value.enumerated.name)); 50 | NTV2_MSG_AUDIO_STATE("%s: enumerate audio item %d - %s\n", 51 | ntv2_aud->name, (int)info->value.enumerated.item, config->name); 52 | } 53 | else { 54 | strlcpy(info->value.enumerated.name, "bad source", sizeof(info->value.enumerated.name)); 55 | NTV2_MSG_AUDIO_ERROR("%s: *error* enumerate bad source\n", 56 | ntv2_aud->name); 57 | } 58 | 59 | return 0; 60 | } 61 | 62 | static int ntv2_mixops_get_source_control(struct snd_kcontrol *kcontrol, 63 | struct snd_ctl_elem_value *elem) 64 | { 65 | struct ntv2_audio *ntv2_aud = (struct ntv2_audio *)snd_kcontrol_chip(kcontrol); 66 | 67 | /* return current index */ 68 | elem->value.enumerated.item[0] = ntv2_aud->snd_input; 69 | 70 | NTV2_MSG_AUDIO_STATE("%s: get audio input %d\n", 71 | ntv2_aud->name, ntv2_aud->snd_input); 72 | 73 | return 0; 74 | } 75 | 76 | static int ntv2_mixops_put_source_control(struct snd_kcontrol *kcontrol, 77 | struct snd_ctl_elem_value *elem) 78 | { 79 | struct ntv2_audio *ntv2_aud = (struct ntv2_audio *)snd_kcontrol_chip(kcontrol); 80 | struct ntv2_source_config *config; 81 | 82 | ntv2_aud->snd_input = elem->value.enumerated.item[0]; 83 | 84 | /* check for valid index */ 85 | config = ntv2_features_get_source_config(ntv2_aud->features, 86 | ntv2_aud->ntv2_chn->index, 87 | ntv2_aud->snd_input); 88 | if (config == NULL) { 89 | ntv2_aud->snd_input = 0; 90 | config = ntv2_features_get_source_config(ntv2_aud->features, 91 | ntv2_aud->ntv2_chn->index, 92 | ntv2_aud->snd_input); 93 | } 94 | 95 | /* set source format */ 96 | ntv2_features_gen_source_format(config, &ntv2_aud->source_format); 97 | 98 | NTV2_MSG_AUDIO_STATE("%s: put audio input %d - %s\n", 99 | ntv2_aud->name, ntv2_aud->snd_input, config->name); 100 | 101 | return 0; 102 | } 103 | 104 | int ntv2_mixops_capture_configure(struct ntv2_audio *ntv2_aud) 105 | { 106 | struct snd_kcontrol_new snd_control; 107 | char control_name[80]; 108 | int ret; 109 | 110 | if (ntv2_aud == NULL) 111 | return -EPERM; 112 | 113 | memset(&snd_control, 0, sizeof(snd_control)); 114 | 115 | snd_control.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 116 | snd_control.name = control_name; 117 | snd_control.count = 1; 118 | snd_control.info = ntv2_mixops_info_source_control; 119 | snd_control.get = ntv2_mixops_get_source_control; 120 | snd_control.put = ntv2_mixops_put_source_control; 121 | 122 | snprintf(control_name, sizeof(control_name), "Channel %d Source Capture Route", 123 | ntv2_aud->ntv2_chn->index + 1); 124 | 125 | ret = snd_ctl_add(ntv2_aud->ntv2_dev->snd_card, snd_ctl_new1(&snd_control, ntv2_aud)); 126 | if (ret != 0) { 127 | NTV2_MSG_AUDIO_ERROR("%s: *error* adding audio control %08x\n", 128 | ntv2_aud->ntv2_dev->name, ret); 129 | } 130 | 131 | return 0; 132 | } 133 | -------------------------------------------------------------------------------- /driver/ntv2_params.c: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 device parameters 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #define NTV2_REG_CONST 21 | #include "ntv2_common.h" 22 | #undef NTV2_REG_CONST 23 | #include "ntv2_register.h" 24 | #include "ntv2_nwlreg.h" 25 | #include "ntv2_xlxreg.h" 26 | 27 | static struct ntv2_module ntv2_mod_info; 28 | 29 | static const char* stream_type_name[ntv2_stream_type_size] = { 30 | "unknown", "video input", "video output", "audio input", "audio output" 31 | }; 32 | 33 | static const char* pci_type_name[ntv2_pci_type_size] = { 34 | "unknown", "nwl", "xlx" 35 | }; 36 | 37 | 38 | /* 39 | * Initialize module info 40 | */ 41 | void ntv2_module_initialize(void) 42 | { 43 | struct ntv2_module *ntv2_mod = &ntv2_mod_info; 44 | 45 | memset(ntv2_mod, 0, sizeof(struct ntv2_module)); 46 | 47 | ntv2_mod->name = NTV2_MODULE_NAME; 48 | ntv2_mod->version = NTV2_DRV_VERSION; 49 | ntv2_mod->uart_max = NTV2_MAX_UARTS; 50 | ntv2_mod->cdev_max = NTV2_MAX_CDEVS; 51 | ntv2_mod->cdev_name = NTV2_CDEV_NAME; 52 | 53 | ntv2_mod->debug_mask = 54 | // NTV2_DEBUG_INPUT_STATE | 55 | // NTV2_DEBUG_HDMIIN_STATE | 56 | // NTV2_DEBUG_HDMIIN_DETECT | 57 | // NTV2_DEBUG_VIDEO_STATE | 58 | // NTV2_DEBUG_VIDEO_STREAM | 59 | // NTV2_DEBUG_CHANNEL_STATE | 60 | // NTV2_DEBUG_CHANNEL_STREAM | 61 | // NTV2_DEBUG_CHANNEL_STATISTICS | 62 | // NTV2_DEBUG_DMA_STATE | 63 | // NTV2_DEBUG_DMA_STREAM | 64 | // NTV2_DEBUG_DMA_DESCRIPTOR | 65 | // NTV2_DEBUG_AUDIO_STATE | 66 | // NTV2_DEBUG_DMA_STATISTICS | 67 | NTV2_DEBUG_INFO | 68 | NTV2_DEBUG_ERROR; 69 | 70 | INIT_LIST_HEAD(&ntv2_mod->device_list); 71 | spin_lock_init(&ntv2_mod->device_lock); 72 | atomic_set(&ntv2_mod->device_index, 0); 73 | atomic_set(&ntv2_mod->uart_index, 0); 74 | 75 | ntv2_mod->init = true; 76 | } 77 | 78 | void ntv2_module_release(void) 79 | { 80 | } 81 | 82 | /* 83 | * Get module info singleton 84 | */ 85 | struct ntv2_module *ntv2_module_info(void) 86 | { 87 | return &ntv2_mod_info; 88 | } 89 | 90 | s64 ntv2_system_time(void) 91 | { 92 | #ifdef NTV2_USE_KTIME 93 | struct timespec64 ts64; 94 | ktime_get_real_ts64(&ts64); 95 | 96 | return ((s64)ts64.tv_sec * 1000000) + (ts64.tv_nsec / 1000); 97 | #else 98 | struct timeval tv; 99 | do_gettimeofday(&tv); 100 | 101 | return ((s64)tv.tv_sec * 1000000 + tv.tv_usec); 102 | #endif 103 | } 104 | 105 | int ntv2_wait(int *event, int state, int timeout) 106 | { 107 | if (event == NULL) 108 | return -EPERM; 109 | 110 | while (timeout > 0) { 111 | if (*event == state) 112 | break; 113 | msleep(1); 114 | timeout -= 1000; 115 | } 116 | if (timeout < 0) 117 | return -ETIME; 118 | 119 | return 0; 120 | } 121 | 122 | const char* ntv2_stream_name(enum ntv2_stream_type type) 123 | { 124 | if (type >= ntv2_stream_type_size) return "bad stream type"; 125 | 126 | return stream_type_name[type]; 127 | } 128 | 129 | 130 | const char* ntv2_pci_name(enum ntv2_pci_type type) 131 | { 132 | if (type >= ntv2_pci_type_size) return "bad pci type"; 133 | 134 | return pci_type_name[type]; 135 | } 136 | 137 | 138 | int ntv2_alloc_scatterlist(struct sg_table *sgt, u8* vm_buffer, u32 vm_size) 139 | { 140 | struct scatterlist *sg; 141 | struct page *pg; 142 | u8 *buf; 143 | unsigned long nents; 144 | int i; 145 | int ret; 146 | 147 | if ((sgt == NULL) || 148 | (vm_buffer == NULL) || 149 | (vm_size == 0)) 150 | return -EPERM; 151 | 152 | /* free the old scatterlist */ 153 | ntv2_free_scatterlist(sgt); 154 | 155 | /* allocate the scatter buffer */ 156 | nents = PAGE_ALIGN(vm_size) >> PAGE_SHIFT; 157 | ret = sg_alloc_table(sgt, nents, GFP_KERNEL); 158 | if (ret < 0) { 159 | return ret; 160 | } 161 | 162 | /* generate the scatter list */ 163 | buf = vm_buffer; 164 | for_each_sg(sgt->sgl, sg, sgt->nents, i) { 165 | pg = vmalloc_to_page(buf); 166 | if (pg == NULL) { 167 | sg_free_table(sgt); 168 | return -ENOMEM; 169 | } 170 | sg_set_page(sg, pg, PAGE_SIZE, 0); 171 | buf += PAGE_SIZE; 172 | } 173 | 174 | return 0; 175 | } 176 | 177 | void ntv2_free_scatterlist(struct sg_table *sgt) 178 | { 179 | if (sgt == NULL) 180 | return; 181 | 182 | sg_free_table(sgt); 183 | } 184 | 185 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ⚠ **WARNING: This Repository is Unmaintained** 2 | 3 | 05/12/2025 4 | 5 | This repository is no longer actively maintained. We appreciate your continued use, but are unable to provide ongoing support, bug fixes, or feature development. 6 | 7 | The team at AJA is developing a replacement project with enhanced functionality, which will be incorporated into our SDK: [https://github.com/aja-video/libajantv2](https://github.com/aja-video/libajantv2). We expect to announce details about the SDK integration in the coming months. Please monitor this repository for updates. 8 | 9 | We recommend caution when using this repository and cannot guarantee stability or compatibility. Thank you for your understanding. 10 | 11 | ![enter image description here](https://www.aja.com/media/images/press/aja/AJA_Logo_small.png) 12 | # NTV2 V4L2/ALSA Kernel Driver 13 | 14 | ## Overview 15 | This repository contains the V4L2/ALSA driver for use with the AJA's NTV2 Video I/O boards. 16 | 17 | The driver has been tested on several Ubuntu versions and Centos 7. 18 | ### Note 19 | The v4l2-ntv2 driver is designed to be a standalone driver. It is impossible to use this driver in conjunction with AJA's main ntv2 kernel driver. Attempting to load both the ntv2 driver and the v4l2 driver will result in both drivers unable to load correctly. 20 | ## Version (tag) 21 | 22 | v1.0.0 initial release - video/audio capture 23 | v1.1.0 add serial port for rovocam 24 | v1.2.0 add audio mixer 25 | v1.2.1 support kernels to 4.6 26 | v1.2.2 support kernels to 4.14 27 | v2.0.0 support Kona HDMI and Kona 1 28 | UHD/4K SDI two sample interleave input 29 | SDI embedded LTC timecode 30 | v2.0.1 support kernels to 5.1 31 | v2.0.2 support kernels to 5.4 32 | v2.0.3 support kernels to 5.6 33 | 34 | ## Requirements 35 | - Linux Kernel (64 bit) v3.10.0 to 5.15.0 (approximately) 36 | - `make` package for your distribution 37 | ## Supported AJA Products 38 | - Kona 4 39 | - Corvid 44 40 | - Corvid 88 41 | - Corvid HB-R 42 | - Kona HDMI 43 | - Kona 1 44 | ## Building the Driver 45 | The v4l2 / alsa driver is located in `/driver`. A simple `make` will build 46 | the driver. If there are build errors they may be due to v4l2 interface 47 | changes. To manage this there are several kernel version #ifdef(s) 48 | in ntv2_common.h. The kernel versions are approximate; you may need 49 | to adjust them for your kernel. 50 | ## Installation 51 | Installation is fairly straight forward. You will need to pull this repo with git, run one make command, and then use the load script to load the driver into the kernel. Note that this driver will need to be loaded on every reboot. 52 | 53 | git clone https://github.com/aja-video/ntv2-v4l2.git 54 | cd ~/ntv2-v4l2/driver 55 | make 56 | sudo ./load 57 | 58 | 59 | ### Note to Centos 7 users 60 | Recent updates of Centos 7 require that `NTV2_USE_SND_CARD_NEW` to be defined in 61 | ntv2_common.h. Uncomment (remove //) this line near the end of the file: 62 | 63 | //#define NTV2_USE_SND_CARD_NEW 64 | 65 | If any system with a pre 3.16 kernel crashes when the driver loads this may also be the solution. 66 | 67 | ## Load / Unload Scrips 68 | The `load` script modprobe(s) several dependencies before loading the ntv2video.ko driver. There is also an unload script. Unloading the driver requires exiting any application that has opened the driver including the system audio mixer (pulseaudio). 69 | 70 | ## Example Use 71 | List the available input devices with `v4l2-ctl`. 72 | 73 | v4l2-ctl --list-devices 74 | 75 | You can capture the content off of an SDI input with `ffplay`. 76 | 77 | ffplay -f v4l2 -i /dev/video0 78 | Note that you can also replace `ffplay` with `ffmpeg` and some additional options to capture the video to disk. 79 | 80 | ffmpeg -f v4l2 -i /dev/video0 -c:v h264 example.mp4 81 | 82 | You can also point VLC to the v4l2 video interface and also the alsa audio interface to capture audio and video. 83 | 84 | vlc alsa:// --input-slave v4l2:// 85 | 86 | ### Honorable mentions 87 | - You can use `qv4l2` to perform simple v4l2 capture. 88 | - `Cheese` is a simple camera application that allows users to capture video or still images. 89 | - `Audacity` can be used in conjunction with the alsa driver to capture audio. 90 | 91 | 92 | 93 | ## License 94 | 95 | Copyright 2016 AJA Video Systems Inc. All rights reserved. 96 | 97 | This program is free software; you may redistribute it and/or modify 98 | it under the terms of the GNU General Public License as published by 99 | the Free Software Foundation; version 2 of the License. 100 | 101 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 102 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 103 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 104 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 105 | BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 106 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 107 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 108 | SOFTWARE. 109 | 110 | -------------------------------------------------------------------------------- /driver/ntv2_register.c: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 PCI register interface 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #include "ntv2_register.h" 21 | 22 | 23 | struct ntv2_register *ntv2_register_open(struct ntv2_object *ntv2_obj, 24 | const char *name, int index) 25 | { 26 | struct ntv2_register *ntv2_reg = NULL; 27 | 28 | ntv2_reg = kzalloc(sizeof(struct ntv2_register), GFP_KERNEL); 29 | if (ntv2_reg == NULL) { 30 | NTV2_MSG_ERROR("%s: ntv2_register instance memory allocation failed\n", ntv2_obj->name); 31 | return NULL; 32 | } 33 | 34 | ntv2_reg->index = index; 35 | snprintf(ntv2_reg->name, NTV2_STRING_SIZE, "%s-%s%d", ntv2_obj->name, name, index); 36 | INIT_LIST_HEAD(&ntv2_reg->list); 37 | ntv2_reg->ntv2_dev = ntv2_obj->ntv2_dev; 38 | 39 | spin_lock_init(&ntv2_reg->rmw_lock); 40 | 41 | return ntv2_reg; 42 | } 43 | 44 | void ntv2_register_close(struct ntv2_register *ntv2_reg) 45 | { 46 | if (ntv2_reg == NULL) 47 | return; 48 | 49 | memset(ntv2_reg, 0, sizeof(struct ntv2_register)); 50 | kfree(ntv2_reg); 51 | } 52 | 53 | int ntv2_register_configure(struct ntv2_register *ntv2_reg, 54 | void __iomem *base, 55 | u32 size) 56 | { 57 | if (ntv2_reg == NULL) 58 | return -EPERM; 59 | 60 | NTV2_MSG_REGISTER_INFO("%s: configure register io\n", ntv2_reg->name); 61 | 62 | if ((base == NULL) || (size == 0)) { 63 | NTV2_MSG_REGISTER_ERROR("%s: *error* bad configuration address 0x%px size 0x%08x\n", 64 | ntv2_reg->name, base, size); 65 | return -EPERM; 66 | } 67 | 68 | ntv2_reg->base = base; 69 | ntv2_reg->size = size; 70 | ntv2_reg->enable = false; 71 | 72 | return 0; 73 | } 74 | 75 | int ntv2_register_enable(struct ntv2_register *ntv2_reg) 76 | { 77 | unsigned long flags; 78 | 79 | if (ntv2_reg == NULL) 80 | return -EPERM; 81 | 82 | spin_lock_irqsave(&ntv2_reg->rmw_lock, flags); 83 | ntv2_reg->enable = true; 84 | spin_unlock_irqrestore(&ntv2_reg->rmw_lock, flags); 85 | 86 | return 0; 87 | } 88 | 89 | int ntv2_register_disable(struct ntv2_register *ntv2_reg) 90 | { 91 | unsigned long flags; 92 | 93 | if (ntv2_reg == NULL) 94 | return -EPERM; 95 | 96 | spin_lock_irqsave(&ntv2_reg->rmw_lock, flags); 97 | ntv2_reg->enable = false; 98 | spin_unlock_irqrestore(&ntv2_reg->rmw_lock, flags); 99 | 100 | return 0; 101 | } 102 | 103 | u32 ntv2_register_read(struct ntv2_register *ntv2_reg, u32 regnum) 104 | { 105 | void __iomem *address = NULL; 106 | unsigned long flags; 107 | u32 data = 0; 108 | 109 | if (ntv2_reg == NULL) 110 | return data; 111 | 112 | /* check bounds */ 113 | if ((ntv2_reg->base == NULL) || 114 | ((regnum*4) >= ntv2_reg->size)) { 115 | NTV2_MSG_REGISTER_ERROR("%s: *error* register read failed regnum %d\n", 116 | ntv2_reg->name, regnum); 117 | return data; 118 | } 119 | 120 | address = (void __iomem*)(((u8*)ntv2_reg->base) + (regnum * 4)); 121 | 122 | spin_lock_irqsave(&ntv2_reg->rmw_lock, flags); 123 | if (ntv2_reg->enable) 124 | data = ioread32(address); 125 | spin_unlock_irqrestore(&ntv2_reg->rmw_lock, flags); 126 | 127 | NTV2_MSG_REGISTER_READ("%s: read reg %4d (0x%08x) data 0x%08x\n", 128 | ntv2_reg->name, regnum, regnum*4, data); 129 | 130 | return data; 131 | } 132 | 133 | void ntv2_register_write(struct ntv2_register *ntv2_reg, u32 regnum, u32 data) 134 | { 135 | void __iomem *address = NULL; 136 | unsigned long flags; 137 | 138 | if (ntv2_reg == NULL) 139 | return; 140 | 141 | /* check bounds */ 142 | if ((ntv2_reg->base == NULL) || 143 | ((regnum*4) >= ntv2_reg->size)) { 144 | NTV2_MSG_REGISTER_ERROR("%s: *error* register read failed regnum %d\n", 145 | ntv2_reg->name, regnum); 146 | return; 147 | } 148 | 149 | address = (void __iomem*)(((u8*)ntv2_reg->base) + (regnum * 4)); 150 | 151 | spin_lock_irqsave(&ntv2_reg->rmw_lock, flags); 152 | if (ntv2_reg->enable) 153 | iowrite32(data, address); 154 | spin_unlock_irqrestore(&ntv2_reg->rmw_lock, flags); 155 | 156 | NTV2_MSG_REGISTER_WRITE("%s: write reg %4d (0x%08x) data 0x%08x\n", 157 | ntv2_reg->name, regnum, regnum*4, data); 158 | } 159 | 160 | u32 ntv2_register_rmw(struct ntv2_register *ntv2_reg, u32 regnum, u32 data, u32 mask) 161 | { 162 | void __iomem *address = NULL; 163 | u32 read_data = 0; 164 | u32 write_data = 0; 165 | unsigned long flags; 166 | 167 | if (ntv2_reg == NULL) 168 | return 0; 169 | 170 | /* check bounds */ 171 | if ((ntv2_reg->base == NULL) || 172 | ((regnum*4) >= ntv2_reg->size)) { 173 | NTV2_MSG_REGISTER_ERROR("%s: *error* register read failed regnum %d\n", 174 | ntv2_reg->name, regnum); 175 | return 0; 176 | } 177 | 178 | address = (void __iomem*)(((u8*)ntv2_reg->base) + (regnum * 4)); 179 | 180 | spin_lock_irqsave(&ntv2_reg->rmw_lock, flags); 181 | if (ntv2_reg->enable) { 182 | read_data = ioread32(address); 183 | write_data = (read_data & ~mask) | (data & mask); 184 | iowrite32(write_data, address); 185 | } 186 | spin_unlock_irqrestore(&ntv2_reg->rmw_lock, flags); 187 | 188 | NTV2_MSG_REGISTER_WRITE("%s: rmw reg %4d (0x%08x) data 0x%08x mask 0x%08x read 0x%08x write 0x%08x\n", 189 | ntv2_reg->name, regnum, regnum*4, data, mask, read_data, write_data); 190 | 191 | return read_data; 192 | } 193 | 194 | u32 ntv2_reg_read(struct ntv2_register *ntv2_reg, const u32 *reg, u32 index) 195 | { 196 | if ((ntv2_reg == NULL) || 197 | (reg == NULL) || 198 | (index >= NTV2_REG_COUNT(reg))) 199 | return 0; 200 | 201 | return ntv2_register_read(ntv2_reg, NTV2_REG_NUM(reg, index)); 202 | } 203 | 204 | void ntv2_reg_write(struct ntv2_register *ntv2_reg, const u32 *reg, u32 index, u32 data) 205 | { 206 | if ((ntv2_reg == NULL) || 207 | (reg == NULL) || 208 | (index >= NTV2_REG_COUNT(reg))) 209 | return; 210 | 211 | ntv2_register_write(ntv2_reg, NTV2_REG_NUM(reg, index), data); 212 | } 213 | 214 | u32 ntv2_reg_rmw(struct ntv2_register *ntv2_reg, const u32 *reg, u32 index, u32 data, u32 mask) 215 | { 216 | if ((ntv2_reg == NULL) || 217 | (reg == NULL) || 218 | (index >= NTV2_REG_COUNT(reg))) 219 | return 0; 220 | 221 | return ntv2_register_rmw(ntv2_reg, NTV2_REG_NUM(reg, index), data, mask); 222 | } 223 | 224 | -------------------------------------------------------------------------------- /driver/ntv2_chrdev.c: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 character device interface 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #include "ntv2_chrdev.h" 21 | #include "ntv2_features.h" 22 | #include "ntv2_register.h" 23 | #include "ntv2_konareg.h" 24 | 25 | struct ntv2_register_access { 26 | u32 number; 27 | u32 value; 28 | u32 mask; 29 | u32 shift; 30 | }; 31 | 32 | #define NTV2_DEVICE_TYPE 0xbb 33 | #define IOCTL_NTV2_WRITE_REGISTER \ 34 | _IOW(NTV2_DEVICE_TYPE, 48, struct ntv2_register_access) 35 | #define IOCTL_NTV2_READ_REGISTER \ 36 | _IOWR(NTV2_DEVICE_TYPE, 49 , struct ntv2_register_access) 37 | 38 | 39 | static int ntv2_open(struct inode *inode, struct file *file) 40 | { 41 | struct ntv2_chrdev *ntv2_chr = container_of(inode->i_cdev, struct ntv2_chrdev, cdev); 42 | 43 | NTV2_MSG_CHRDEV_STATE("%s: file open\n", ntv2_chr->name); 44 | 45 | file->private_data = ntv2_chr; 46 | 47 | return 0; 48 | } 49 | 50 | static int ntv2_release(struct inode *inode, struct file *file) 51 | { 52 | struct ntv2_chrdev *ntv2_chr = (struct ntv2_chrdev *)file->private_data; 53 | 54 | NTV2_MSG_CHRDEV_STATE("%s: file release\n", ntv2_chr->name); 55 | 56 | return 0; 57 | } 58 | 59 | static long ntv2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 60 | { 61 | struct ntv2_chrdev *ntv2_chr = (struct ntv2_chrdev *)file->private_data; 62 | struct ntv2_register_access ra; 63 | u32 read_value; 64 | u32 write_value; 65 | 66 | // NTV2_MSG_CHRDEV_STATE("%s: file ioctl cmd %08x\n", ntv2_chr->name, cmd); 67 | 68 | switch (cmd) { 69 | case IOCTL_NTV2_WRITE_REGISTER: 70 | if(copy_from_user((void*)&ra, (const void*)arg, sizeof(struct ntv2_register_access))) 71 | return -EFAULT; 72 | 73 | if (ra.number == NTV2_DEBUG_REGISTER) { 74 | ntv2_module_info()->debug_mask = ra.value; 75 | break; 76 | } 77 | 78 | write_value = ra.value; 79 | if (ra.mask != 0xffffffff) { 80 | read_value = ntv2_register_read(ntv2_chr->vid_reg, ra.number); 81 | read_value &= ~ra.mask; 82 | write_value = (write_value << ra.shift) & ra.mask; 83 | write_value |= read_value; 84 | } 85 | ntv2_register_write(ntv2_chr->vid_reg, ra.number, write_value); 86 | break; 87 | 88 | case IOCTL_NTV2_READ_REGISTER: 89 | if(copy_from_user((void*)&ra, (const void*)arg, sizeof(struct ntv2_register_access))) 90 | return -EFAULT; 91 | 92 | if (ra.number == NTV2_DEBUG_REGISTER) { 93 | ra.value = ntv2_module_info()->debug_mask; 94 | } else if (ra.number == 70) { 95 | ra.value = 0; 96 | } else { 97 | ra.value = ntv2_register_read(ntv2_chr->vid_reg, ra.number); 98 | ra.value = (ra.value & ra.mask) >> ra.shift; 99 | } 100 | 101 | if(copy_to_user((void*)arg, (const void*)&ra, sizeof(struct ntv2_register_access))) 102 | return -EFAULT; 103 | break; 104 | default: 105 | return -EFAULT; 106 | } 107 | 108 | return 0; 109 | } 110 | 111 | static int ntv2_mmap(struct file *file, struct vm_area_struct* vma) 112 | { 113 | return 0; 114 | } 115 | 116 | static loff_t ntv2_llseek(struct file *file, loff_t off, int whence) 117 | { 118 | return 0; 119 | } 120 | 121 | static ssize_t ntv2_read(struct file *file, char *buf, size_t count, loff_t *f_pos) 122 | { 123 | return 0; 124 | } 125 | 126 | static ssize_t ntv2_write(struct file *file, const char *buf, size_t count, loff_t *f_pos) 127 | { 128 | return 0; 129 | } 130 | 131 | static struct file_operations ntv2_file_ops = 132 | { 133 | .owner = THIS_MODULE, 134 | .open = ntv2_open, 135 | .release = ntv2_release, 136 | .unlocked_ioctl = ntv2_ioctl, 137 | .mmap = ntv2_mmap, 138 | .llseek = ntv2_llseek, 139 | .read = ntv2_read, 140 | .write = ntv2_write 141 | }; 142 | 143 | struct ntv2_chrdev *ntv2_chrdev_open(struct ntv2_object *ntv2_obj, 144 | const char *name, int index) 145 | { 146 | struct ntv2_chrdev *ntv2_chr = NULL; 147 | 148 | ntv2_chr = kzalloc(sizeof(struct ntv2_chrdev), GFP_KERNEL); 149 | if (ntv2_chr == NULL) { 150 | NTV2_MSG_ERROR("%s: ntv2_chrdev instance memory allocation failed\n", ntv2_obj->name); 151 | return NULL; 152 | } 153 | 154 | ntv2_chr->index = index; 155 | snprintf(ntv2_chr->name, NTV2_STRING_SIZE, "%s-%s%d", ntv2_obj->name, name, index); 156 | INIT_LIST_HEAD(&ntv2_chr->list); 157 | ntv2_chr->ntv2_dev = ntv2_obj->ntv2_dev; 158 | 159 | spin_lock_init(&ntv2_chr->state_lock); 160 | 161 | NTV2_MSG_CHRDEV_INFO("%s: open ntv2_chrdev\n", ntv2_chr->name); 162 | 163 | return ntv2_chr; 164 | } 165 | 166 | void ntv2_chrdev_close(struct ntv2_chrdev *ntv2_chr) 167 | { 168 | if (ntv2_chr == NULL) 169 | return; 170 | 171 | NTV2_MSG_CHRDEV_INFO("%s: close ntv2_chrdev\n", ntv2_chr->name); 172 | 173 | ntv2_chrdev_disable(ntv2_chr); 174 | 175 | if (ntv2_chr->cdev.ops != NULL) { 176 | cdev_del(&ntv2_chr->cdev); 177 | ntv2_chr->cdev.ops = NULL; 178 | } 179 | 180 | memset(ntv2_chr, 0, sizeof(struct ntv2_chrdev)); 181 | kfree(ntv2_chr); 182 | } 183 | 184 | int ntv2_chrdev_configure(struct ntv2_chrdev *ntv2_chr, 185 | struct ntv2_features *features, 186 | struct ntv2_register *vid_reg) 187 | { 188 | struct ntv2_module *ntv2_mod = ntv2_module_info(); 189 | int index; 190 | int res; 191 | 192 | if ((ntv2_chr == NULL) || 193 | (features == NULL) || 194 | (vid_reg == NULL)) 195 | return -EPERM; 196 | 197 | NTV2_MSG_CHRDEV_INFO("%s: configure cdev\n", ntv2_chr->name); 198 | 199 | ntv2_chr->features = features; 200 | ntv2_chr->vid_reg = vid_reg; 201 | 202 | /* get next character device index */ 203 | index = atomic_inc_return(&ntv2_mod->cdev_index) - 1; 204 | if (index >= ntv2_mod->cdev_max) { 205 | NTV2_MSG_CHRDEV_ERROR("%s: ntv2_cdev too many character devices %d\n", ntv2_chr->name, index); 206 | return -ENOMEM; 207 | } 208 | 209 | /* add new character device */ 210 | cdev_init(&ntv2_chr->cdev, &ntv2_file_ops); 211 | ntv2_chr->cdev.owner = THIS_MODULE; 212 | 213 | res = cdev_add(&ntv2_chr->cdev, 214 | MKDEV(MAJOR(ntv2_mod->cdev_number), index), 215 | 1); 216 | if (res < 0) { 217 | NTV2_MSG_CHRDEV_ERROR("%s: *error* cdev_add() device %d failed code %d\n", 218 | ntv2_chr->name, index, res); 219 | return res; 220 | } 221 | 222 | return 0; 223 | } 224 | 225 | int ntv2_chrdev_enable(struct ntv2_chrdev *ntv2_chr) 226 | { 227 | unsigned long flags; 228 | 229 | if (ntv2_chr == NULL) 230 | return -EPERM; 231 | 232 | if (ntv2_chr->task_state == ntv2_task_state_enable) 233 | return 0; 234 | 235 | NTV2_MSG_CHRDEV_STATE("%s: file ops enable\n", ntv2_chr->name); 236 | 237 | spin_lock_irqsave(&ntv2_chr->state_lock, flags); 238 | ntv2_chr->task_state = ntv2_task_state_enable; 239 | spin_unlock_irqrestore(&ntv2_chr->state_lock, flags); 240 | 241 | return 0; 242 | } 243 | 244 | int ntv2_chrdev_disable(struct ntv2_chrdev *ntv2_chr) 245 | { 246 | unsigned long flags; 247 | 248 | if (ntv2_chr == NULL) 249 | return -EPERM; 250 | 251 | if (ntv2_chr->task_state != ntv2_task_state_enable) 252 | return 0; 253 | 254 | NTV2_MSG_INPUT_STATE("%s: file ops disable\n", ntv2_chr->name); 255 | 256 | spin_lock_irqsave(&ntv2_chr->state_lock, flags); 257 | ntv2_chr->task_state = ntv2_task_state_disable; 258 | spin_unlock_irqrestore(&ntv2_chr->state_lock, flags); 259 | 260 | return 0; 261 | } 262 | 263 | 264 | -------------------------------------------------------------------------------- /driver/ntv2_channel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 hardware channel interface 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_CHANNEL_H 21 | #define NTV2_CHANNEL_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | #define NTV2_MAX_CHANNEL_STREAMS 8 26 | #define NTV2_MAX_CHANNEL_BUFFERS 64 27 | #define NTV2_CHANNEL_STATISTIC_INTERVAL 5000000 28 | 29 | enum ntv2_channel_state { 30 | ntv2_channel_state_unknown, 31 | ntv2_channel_state_idle, 32 | ntv2_channel_state_run, 33 | ntv2_channel_state_size 34 | }; 35 | 36 | struct ntv2_features; 37 | 38 | typedef void (*ntv2_channel_callback)(unsigned long); 39 | 40 | struct ntv2_channel_status { 41 | bool interrupt_input; 42 | bool interrupt_output; 43 | v4l2_time_t interrupt_time; 44 | u32 interrupt_rate; 45 | u32 audio_input_offset; 46 | u32 audio_output_offset; 47 | s64 stat_time; 48 | }; 49 | 50 | struct ntv2_video_data { 51 | u32 frame_number; 52 | u32 address; 53 | u32 data_size; 54 | u32 timecode_low; 55 | u32 timecode_high; 56 | bool timecode_present; 57 | }; 58 | 59 | struct ntv2_audio_data { 60 | u32 offset; 61 | u32 address[2]; 62 | u32 data_size[2]; 63 | u32 num_channels; 64 | u32 sample_size; 65 | }; 66 | 67 | struct ntv2_stream_data { 68 | int index; 69 | struct list_head list; 70 | struct ntv2_channel_stream *ntv2_str; 71 | 72 | enum ntv2_stream_type type; 73 | v4l2_time_t timestamp; 74 | 75 | union { 76 | struct ntv2_video_data video; 77 | struct ntv2_audio_data audio; 78 | }; 79 | }; 80 | 81 | struct ntv2_video_stream { 82 | struct ntv2_video_format video_format; 83 | struct ntv2_pixel_format pixel_format; 84 | struct ntv2_input_format input_format; 85 | 86 | u32 frame_first; 87 | u32 frame_last; 88 | u32 frame_size; 89 | bool hardware_enable[NTV2_MAX_CHANNELS]; 90 | 91 | int csc_index; 92 | int num_cscs; 93 | 94 | struct ntv2_stream_data *frame_active; 95 | struct ntv2_stream_data *frame_next; 96 | 97 | s64 total_frame_count; 98 | s64 total_drop_count; 99 | s64 stat_frame_count; 100 | s64 stat_drop_count; 101 | s64 last_display_time; 102 | }; 103 | 104 | struct ntv2_audio_stream { 105 | struct ntv2_source_format source_format; 106 | struct ntv2_source_format auto_format; 107 | 108 | u32 sample_rate; 109 | u32 num_channels; 110 | u32 sample_size; 111 | u32 audio_offset; 112 | u32 ring_address; 113 | u32 ring_offset; 114 | u32 ring_size; 115 | u32 ring_init; 116 | u32 sync_cadence; 117 | u32 sync_tolerance; 118 | bool hardware_enable; 119 | bool embedded_clock; 120 | 121 | s64 total_sample_count; 122 | s64 total_transfer_count; 123 | s64 total_drop_count; 124 | s64 stat_sample_count; 125 | s64 stat_drop_count; 126 | s64 last_display_time; 127 | }; 128 | 129 | struct ntv2_stream_ops { 130 | int (*setup)(struct ntv2_channel_stream *stream); 131 | int (*release)(struct ntv2_channel_stream *stream); 132 | int (*update_mode)(struct ntv2_channel_stream *stream); 133 | int (*update_timing)(struct ntv2_channel_stream *stream); 134 | int (*update_format)(struct ntv2_channel_stream *stream); 135 | int (*update_route)(struct ntv2_channel_stream *stream); 136 | int (*interrupt)(struct ntv2_channel_stream *stream); 137 | }; 138 | 139 | struct ntv2_channel_stream { 140 | enum ntv2_stream_type type; 141 | struct ntv2_channel *ntv2_chn; 142 | 143 | int channel_index; 144 | int num_channels; 145 | 146 | bool capture; 147 | bool queue_enable; 148 | bool queue_run; 149 | bool queue_last; 150 | ntv2_channel_callback frame_callback_func; 151 | unsigned long frame_callback_data; 152 | v4l2_time_t timestamp; 153 | 154 | struct ntv2_stream_data data_array[NTV2_MAX_CHANNEL_BUFFERS]; 155 | struct list_head data_ready_list; 156 | struct list_head data_done_list; 157 | 158 | struct ntv2_stream_ops ops; 159 | union { 160 | struct ntv2_video_stream video; 161 | struct ntv2_audio_stream audio; 162 | }; 163 | }; 164 | 165 | struct ntv2_channel { 166 | int index; 167 | char name[NTV2_STRING_SIZE]; 168 | struct list_head list; 169 | struct ntv2_device *ntv2_dev; 170 | int ref_count; 171 | 172 | struct ntv2_features *features; 173 | struct ntv2_register *vid_reg; 174 | 175 | enum ntv2_channel_state state; 176 | spinlock_t state_lock; 177 | 178 | struct tasklet_struct int_dpc; 179 | spinlock_t int_lock; 180 | struct ntv2_channel_status int_status; 181 | struct ntv2_channel_status dpc_status; 182 | 183 | struct ntv2_channel_stream *streams[ntv2_stream_type_size]; 184 | }; 185 | 186 | struct ntv2_channel *ntv2_channel_open(struct ntv2_object *ntv2_obj, 187 | const char *name, int index); 188 | void ntv2_channel_close(struct ntv2_channel *ntv2_chn); 189 | 190 | int ntv2_channel_configure(struct ntv2_channel *ntv2_chn, 191 | struct ntv2_features *features, 192 | struct ntv2_register *vid_reg); 193 | 194 | void ntv2_channel_disable_all(struct ntv2_channel *ntv2_chn); 195 | 196 | struct ntv2_channel_stream *ntv2_channel_stream(struct ntv2_channel *ntv2_chn, 197 | enum ntv2_stream_type stype); 198 | 199 | int ntv2_channel_set_video_format(struct ntv2_channel_stream *stream, 200 | struct ntv2_video_format *vidf); 201 | 202 | int ntv2_channel_get_video_format(struct ntv2_channel_stream *stream, 203 | struct ntv2_video_format *vidf); 204 | 205 | int ntv2_channel_set_pixel_format(struct ntv2_channel_stream *stream, 206 | struct ntv2_pixel_format *pixf); 207 | 208 | int ntv2_channel_get_pixel_format(struct ntv2_channel_stream *stream, 209 | struct ntv2_pixel_format *pixf); 210 | 211 | int ntv2_channel_set_input_format(struct ntv2_channel_stream *stream, 212 | struct ntv2_input_format *inpf); 213 | 214 | int ntv2_channel_get_input_format(struct ntv2_channel_stream *stream, 215 | struct ntv2_input_format *inpf); 216 | 217 | int ntv2_channel_set_source_format(struct ntv2_channel_stream *stream, 218 | struct ntv2_source_format *souf); 219 | 220 | int ntv2_channel_get_source_format(struct ntv2_channel_stream *stream, 221 | struct ntv2_source_format *souf); 222 | 223 | int ntv2_channel_set_frame_callback(struct ntv2_channel_stream *stream, 224 | ntv2_channel_callback func, 225 | unsigned long data); 226 | 227 | int ntv2_channel_enable(struct ntv2_channel_stream *stream); 228 | int ntv2_channel_disable(struct ntv2_channel_stream *stream); 229 | 230 | int ntv2_channel_start(struct ntv2_channel_stream *stream); 231 | int ntv2_channel_stop(struct ntv2_channel_stream *stream); 232 | int ntv2_channel_flush(struct ntv2_channel_stream *stream); 233 | 234 | struct ntv2_stream_data *ntv2_channel_data_ready(struct ntv2_channel_stream *stream); 235 | void ntv2_channel_data_done(struct ntv2_stream_data *ntv2_data); 236 | 237 | int ntv2_channel_interrupt(struct ntv2_channel *ntv2_chn, 238 | struct ntv2_interrupt_status* irq_status); 239 | #endif 240 | -------------------------------------------------------------------------------- /driver/ntv2_nwlreg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 Northwest Logic register constants 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_NWLREG_H 21 | #define NTV2_NWLREG_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | /* nwl dma engine capabilities registers */ 26 | NTV2_REG(ntv2_nwldma_reg_capabilities, 0x0, 0x40, 0x80, 0xc0, 0x800, 0x840, 0x880, 0x8c0); 27 | NTV2_FLD(ntv2_nwldma_fld_present, 1, 0); /* Indicates DMA Engine present at this location */ 28 | NTV2_FLD(ntv2_nwldma_fld_engine_direction, 1, 1); /* Indicates DMA data flow direction */ 29 | NTV2_CON(ntv2_nwldma_con_system_to_card, 0); /* DMA engine transfers from system to card */ 30 | NTV2_CON(ntv2_nwldma_con_card_to_system, 1); /* DMA engine transfers from card to system */ 31 | NTV2_FLD(ntv2_nwldma_fld_engine_type, 2, 4); /* Indicates the type of DMA Engine that this register set controls */ 32 | NTV2_CON(ntv2_nwldma_con_block_dma, 0); /* DMA engine transfers data in block mode */ 33 | NTV2_CON(ntv2_nwldma_con_packet_dma, 1); /* DMA engine transfers data in packet mode */ 34 | NTV2_FLD(ntv2_nwldma_fld_engine_number, 8, 8); /* Identifies which DMA engine this register set controls */ 35 | NTV2_FLD(ntv2_nwldma_fld_address_size, 8, 16); /* Identifies the size of the card address space */ 36 | 37 | /* control interrupt generation and report dma engine status registers */ 38 | NTV2_REG(ntv2_nwldma_reg_engine_control_status, 0x1, 0x41, 0x81, 0xc1, 0x801, 0x841, 0x881, 0x8c1); 39 | NTV2_FLD(ntv2_nwldma_fld_interrupt_enable, 1, 0); /* Enables/disables the generation of interrupts for this DMA Engine */ 40 | NTV2_FLD(ntv2_nwldma_fld_interrupt_active, 1, 1); /* Interrupt_Active (write a 1 to clear) */ 41 | NTV2_FLD(ntv2_nwldma_fld_chain_start, 1, 8); /* Setting this bit starts the Descriptor Engine */ 42 | NTV2_FLD(ntv2_nwldma_fld_status_dma_reset_request, 1, 9); /* Software sets this bit to abort a DMA operation in process */ 43 | NTV2_FLD(ntv2_nwldma_fld_chain_running, 1, 10); /* 1 = DMA descriptor chain running */ 44 | NTV2_FLD(ntv2_nwldma_fld_chain_complete, 1, 11); /* 1 = DMA descriptor chain complete */ 45 | NTV2_FLD(ntv2_nwldma_fld_chain_error_short, 1, 12); /* Set whenever a chain completes due to an error */ 46 | NTV2_FLD(ntv2_nwldma_fld_chain_software_short, 1, 13); /* Set whenever a chain completes due to a software requested stop */ 47 | NTV2_FLD(ntv2_nwldma_fld_chain_hardware_short, 1, 14); /* Set whenever a chain completes due to a software requested stop */ 48 | NTV2_FLD(ntv2_nwldma_fld_alignment_error, 1, 15); /* Set whenever Chain_Start_Descriptor_Pointer is not aligned */ 49 | NTV2_FLD(ntv2_nwldma_fld_dma_reset, 1, 23); /* Write 1 to reset the DMA Engine */ 50 | 51 | /* first descriptor low address registers */ 52 | NTV2_REG(ntv2_nwldma_reg_chain_start_address_low, 0x2, 0x42, 0x82, 0xc2, 0x802, 0x842, 0x882, 0x8c2); 53 | /* first descriptor high address registers */ 54 | NTV2_REG(ntv2_nwldma_reg_chain_start_address_high, 0x3, 0x43, 0x83, 0xc3, 0x803, 0x843, 0x883, 0x8c3); 55 | /* hardware dma time (nanoseconds) registers */ 56 | NTV2_REG(ntv2_nwldma_reg_hardware_time, 0x4, 0x44, 0x84, 0xc4, 0x804, 0x844, 0x884, 0x8c4); 57 | /* hardware dma bytes transferred registers */ 58 | NTV2_REG(ntv2_nwldma_reg_chain_complete_byte_count, 0x5, 0x45, 0x85, 0xc5, 0x805, 0x845, 0x885, 0x8c5); 59 | 60 | /* nwl dma common control status register */ 61 | NTV2_REG(ntv2_nwldma_reg_common_control_status, 0x1000); 62 | NTV2_FLD(ntv2_nwldma_fld_dma_interrupt_enable, 1, 0); /* Globally enables/disables interrupts for all DMA Engines */ 63 | NTV2_FLD(ntv2_nwldma_fld_dma_interrupt_active, 1, 1); /* Reflects the state of the DMA interrupt hardware output */ 64 | NTV2_FLD(ntv2_nwldma_fld_dma_interrupt_pending, 1, 2); /* Reflects the state of the DMA interrupt */ 65 | NTV2_FLD(ntv2_nwldma_fld_interrupt_mode, 1, 3); /* 0 = Legacy, 1 = MSI */ 66 | NTV2_FLD(ntv2_nwldma_fld_user_interrupt_enable, 1, 4); /* Enables/disables the generation of user interrupts */ 67 | NTV2_FLD(ntv2_nwldma_fld_user_interrupt_active, 1, 5); /* Reflects the state of user interrupt */ 68 | NTV2_FLD(ntv2_nwldma_fld_max_payload_size, 3, 8); /* Maximum payload size used by the DMA back-end core */ 69 | NTV2_CON(ntv2_nwldma_con_playload_size_128_bytes, 0); /* 128 byte payload */ 70 | NTV2_CON(ntv2_nwldma_con_playload_size_256_bytes, 1); /* 256 byte payload */ 71 | NTV2_CON(ntv2_nwldma_con_playload_size_512_bytes, 2); /* 512 byte payload */ 72 | NTV2_FLD(ntv2_nwldma_fld_max_read_request_size, 3, 12); /* Maximum read request size used by the DMA back-end core */ 73 | NTV2_CON(ntv2_nwldma_con_request_size_128_bytes, 0); /* 128 byte read request size */ 74 | NTV2_CON(ntv2_nwldma_con_request_size_256_bytes, 1); /* 256 byte read request size */ 75 | NTV2_CON(ntv2_nwldma_con_request_size_512_bytes, 2); /* 512 byte read request size */ 76 | NTV2_FLD(ntv2_nwldma_fld_s2c_interrupt_status_0, 1, 16); /* System to card DMA engine 0 interrupt active bit */ 77 | NTV2_FLD(ntv2_nwldma_fld_s2c_interrupt_status_1, 1, 17); /* System to card DMA engine 1 interrupt active bit */ 78 | NTV2_FLD(ntv2_nwldma_fld_s2c_interrupt_status_2, 1, 18); /* System to card DMA engine 2 interrupt active bit */ 79 | NTV2_FLD(ntv2_nwldma_fld_s2c_interrupt_status_3, 1, 19); /* System to card DMA engine 3 interrupt active bit */ 80 | NTV2_FLD(ntv2_nwldma_fld_s2c_interrupt_status_4, 1, 20); /* System to card DMA engine 4 interrupt active bit */ 81 | NTV2_FLD(ntv2_nwldma_fld_s2c_interrupt_status_5, 1, 21); /* System to card DMA engine 5 interrupt active bit */ 82 | NTV2_FLD(ntv2_nwldma_fld_s2c_interrupt_status_6, 1, 22); /* System to card DMA engine 6 interrupt active bit */ 83 | NTV2_FLD(ntv2_nwldma_fld_s2c_interrupt_status_7, 1, 23); /* System to card DMA engine 7 interrupt active bit */ 84 | NTV2_FLD(ntv2_nwldma_fld_c2s_interrupt_status_0, 1, 24); /* Card to system DMA engine 0 interrupt active bit */ 85 | NTV2_FLD(ntv2_nwldma_fld_c2s_interrupt_status_1, 1, 25); /* Card to system DMA engine 1 interrupt active bit */ 86 | NTV2_FLD(ntv2_nwldma_fld_c2s_interrupt_status_2, 1, 26); /* Card to system DMA engine 2 interrupt active bit */ 87 | NTV2_FLD(ntv2_nwldma_fld_c2s_interrupt_status_3, 1, 27); /* Card to system DMA engine 3 interrupt active bit */ 88 | NTV2_FLD(ntv2_nwldma_fld_c2s_interrupt_status_4, 1, 28); /* Card to system DMA engine 4 interrupt active bit */ 89 | NTV2_FLD(ntv2_nwldma_fld_c2s_interrupt_status_5, 1, 29); /* Card to system DMA engine 5 interrupt active bit */ 90 | NTV2_FLD(ntv2_nwldma_fld_c2s_interrupt_status_6, 1, 30); /* Card to system DMA engine 6 interrupt active bit */ 91 | NTV2_FLD(ntv2_nwldma_fld_c2s_interrupt_status_7, 1, 31); /* Card to system DMA engine 7 interrupt active bit */ 92 | 93 | /* version registers */ 94 | NTV2_REG(ntv2_nwldma_reg_backend_core_version, 0x1001); /* Version of DMA back-end core */ 95 | NTV2_REG(ntv2_nwldma_reg_pci_express_core_version, 0x1002); /* Version of PCI express core that is connected to the DMA back-end */ 96 | NTV2_REG(ntv2_nwldma_reg_user_version, 0x1003); /* Version of User firmware */ 97 | 98 | /* nwl dma descriptor control bits */ 99 | NTV2_FLD(ntv2_nwldma_fld_control_irq_on_completion, 1, 0); 100 | NTV2_FLD(ntv2_nwldma_fld_control_irq_on_short_err, 1, 1); 101 | NTV2_FLD(ntv2_nwldma_fld_control_irq_on_short_sw, 1, 2); 102 | NTV2_FLD(ntv2_nwldma_fld_control_irq_on_short_hw, 1, 3); 103 | NTV2_FLD(ntv2_nwldma_fld_control_sequence, 1, 4); 104 | NTV2_FLD(ntv2_nwldma_fld_control_continue, 1, 5); 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /driver/ntv2_driver.c: -------------------------------------------------------------------------------- 1 | /* 2 | * AJA NTV2 video for linux driver 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #include "ntv2_common.h" 21 | #include "ntv2_device.h" 22 | #include "ntv2_nwldma.h" 23 | 24 | MODULE_DESCRIPTION("AJA NTV2 V4L2 Driver"); 25 | MODULE_AUTHOR("AJA Video Systems Inc. (http://www.aja.com)"); 26 | MODULE_LICENSE("GPL v2"); 27 | 28 | 29 | static int ntv2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 30 | { 31 | struct ntv2_module *ntv2_mod = ntv2_module_info(); 32 | struct ntv2_device *ntv2_dev = NULL; 33 | unsigned long flags; 34 | int index; 35 | int result; 36 | 37 | /* enable device */ 38 | result = pci_enable_device(pdev); 39 | if (result != 0) { 40 | NTV2_MSG_ERROR("%s: pci_enable_device failed code %d\n", 41 | NTV2_MODULE_NAME, result); 42 | return result; 43 | } 44 | 45 | /* allocate and initialize ntv2 device instance */ 46 | index = atomic_inc_return(&ntv2_mod->device_index) - 1; 47 | ntv2_dev = ntv2_device_open(ntv2_mod, "dev", index); 48 | 49 | NTV2_MSG_INFO("%s: device probe start\n", ntv2_dev->name); 50 | 51 | /* set drvdata */ 52 | dev_set_drvdata(&pdev->dev, ntv2_dev); 53 | 54 | result = ntv2_device_configure(ntv2_dev, pdev); 55 | if (result != 0) 56 | goto disable_device; 57 | 58 | /* add to the device list */ 59 | spin_lock_irqsave(&ntv2_mod->device_lock, flags); 60 | list_add_tail(&ntv2_dev->list, &ntv2_mod->device_list); 61 | spin_unlock_irqrestore(&ntv2_mod->device_lock, flags); 62 | 63 | NTV2_MSG_INFO("%s: device probe complete\n", ntv2_dev->name); 64 | 65 | return 0; 66 | 67 | disable_device: 68 | NTV2_MSG_ERROR("%s: device probe failed code %d\n", 69 | ntv2_dev->name, result); 70 | 71 | ntv2_device_close(ntv2_dev); 72 | pci_disable_device(pdev); 73 | return result; 74 | } 75 | 76 | static int ntv2_suspend(struct pci_dev *pdev, pm_message_t state) 77 | { 78 | struct ntv2_device *ntv2_dev = dev_get_drvdata(&pdev->dev); 79 | 80 | NTV2_MSG_INFO("%s: suspend device\n", ntv2_dev->name); 81 | 82 | ntv2_device_suspend(ntv2_dev); 83 | /* 84 | pci_disable_device(pdev); 85 | pci_save_state(pdev); 86 | */ 87 | return 0; 88 | } 89 | 90 | static int ntv2_resume(struct pci_dev *pdev) 91 | { 92 | struct ntv2_device *ntv2_dev = dev_get_drvdata(&pdev->dev); 93 | 94 | NTV2_MSG_INFO("%s: resume device\n", ntv2_dev->name); 95 | /* 96 | pci_restore_state(pdev); 97 | pci_enable_device(pdev); 98 | pci_set_master(pdev); 99 | */ 100 | ntv2_device_resume(ntv2_dev); 101 | 102 | return 0; 103 | } 104 | 105 | static void ntv2_remove(struct pci_dev *pdev) 106 | { 107 | struct ntv2_device *ntv2_dev = dev_get_drvdata(&pdev->dev); 108 | struct ntv2_module *ntv2_mod = ntv2_dev->ntv2_mod; 109 | unsigned long flags; 110 | 111 | NTV2_MSG_INFO("%s: remove device\n", ntv2_dev->name); 112 | 113 | spin_lock_irqsave(&ntv2_mod->device_lock, flags); 114 | list_del_init(&ntv2_dev->list); 115 | spin_unlock_irqrestore(&ntv2_mod->device_lock, flags); 116 | 117 | ntv2_device_close(ntv2_dev); 118 | pci_disable_device(pdev); 119 | } 120 | 121 | static void ntv2_shutdown(struct pci_dev *pdev) 122 | { 123 | struct ntv2_device *ntv2_dev = dev_get_drvdata(&pdev->dev); 124 | 125 | NTV2_MSG_INFO("%s: shutdown\n", ntv2_dev->name); 126 | } 127 | 128 | #ifdef NTV2_USE_PCI_CHANNEL_STATE_T 129 | static pci_ers_result_t ntv2_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) 130 | #else 131 | static pci_ers_result_t ntv2_pci_error_detected(struct pci_dev *pdev, enum pci_channel_state state) 132 | #endif 133 | { 134 | struct ntv2_device *ntv2_dev = dev_get_drvdata(&pdev->dev); 135 | 136 | NTV2_MSG_ERROR("%s: pci error state %d\n", ntv2_dev->name, state); 137 | 138 | /* stop pci access? */ 139 | 140 | if (state == pci_channel_io_perm_failure) 141 | return PCI_ERS_RESULT_DISCONNECT; 142 | if (state == pci_channel_io_frozen) 143 | return PCI_ERS_RESULT_NEED_RESET; 144 | return PCI_ERS_RESULT_CAN_RECOVER; 145 | } 146 | 147 | static pci_ers_result_t ntv2_pci_slot_reset(struct pci_dev *pdev) 148 | { 149 | struct ntv2_device *ntv2_dev = dev_get_drvdata(&pdev->dev); 150 | 151 | NTV2_MSG_INFO("%s: pci slot reset\n", ntv2_dev->name); 152 | return 0; 153 | } 154 | 155 | static void ntv2_pci_error_resume(struct pci_dev *pdev) 156 | { 157 | struct ntv2_device *ntv2_dev = dev_get_drvdata(&pdev->dev); 158 | 159 | NTV2_MSG_INFO("%s: pci resume\n", ntv2_dev->name); 160 | } 161 | 162 | static struct uart_driver ntv2_uart_driver = { 163 | .owner = THIS_MODULE, 164 | .driver_name = NTV2_MODULE_NAME, 165 | .dev_name = NTV2_TTY_NAME, 166 | .nr = NTV2_MAX_UARTS, 167 | }; 168 | 169 | static const struct pci_device_id ntv2_pci_tbl[] = { 170 | { 171 | NTV2_PCI_VENID, NTV2_PCI_DEVID_KONA4, 172 | PCI_ANY_ID, PCI_ANY_ID, 173 | 0, 0, 174 | 0 175 | }, 176 | { 177 | NTV2_PCI_VENID, NTV2_PCI_DEVID_CORVID88, 178 | PCI_ANY_ID, PCI_ANY_ID, 179 | 0, 0, 180 | 0 181 | }, 182 | { 183 | NTV2_PCI_VENID, NTV2_PCI_DEVID_CORVID44, 184 | PCI_ANY_ID, PCI_ANY_ID, 185 | 0, 0, 186 | 0 187 | }, 188 | { 189 | NTV2_PCI_VENID, NTV2_PCI_DEVID_CORVIDHBR, 190 | PCI_ANY_ID, PCI_ANY_ID, 191 | 0, 0, 192 | 0 193 | }, 194 | { 195 | NTV2_PCI_VENID, NTV2_PCI_DEVID_KONAHDMI, 196 | PCI_ANY_ID, PCI_ANY_ID, 197 | 0, 0, 198 | 0 199 | }, 200 | { 201 | NTV2_PCI_VENID, NTV2_PCI_DEVID_KONA1, 202 | PCI_ANY_ID, PCI_ANY_ID, 203 | 0, 0, 204 | 0 205 | }, 206 | { 0, 0, 0, 0, 0, 0, 0 } 207 | }; 208 | MODULE_DEVICE_TABLE(pci, ntv2_pci_tbl); 209 | 210 | static const struct pci_error_handlers ntv2_pci_errors = { 211 | .error_detected = ntv2_pci_error_detected, 212 | .slot_reset = ntv2_pci_slot_reset, 213 | .resume = ntv2_pci_error_resume, 214 | }; 215 | 216 | static struct pci_driver ntv2_pci_driver = { 217 | .name = NTV2_MODULE_NAME, 218 | .id_table = ntv2_pci_tbl, 219 | .probe = ntv2_probe, 220 | .suspend = ntv2_suspend, 221 | .resume = ntv2_resume, 222 | .remove = ntv2_remove, 223 | .err_handler = &ntv2_pci_errors, 224 | .shutdown = ntv2_shutdown, 225 | }; 226 | 227 | static int __init ntv2_module_init(void) 228 | { 229 | struct ntv2_module *ntv2_mod = NULL; 230 | int result; 231 | 232 | /* initialize device module info */ 233 | ntv2_module_initialize(); 234 | ntv2_mod = ntv2_module_info(); 235 | 236 | NTV2_MSG_INFO("%s: module init version %s\n", ntv2_mod->name, ntv2_mod->version); 237 | 238 | /* register uart driver */ 239 | result = uart_register_driver(&ntv2_uart_driver); 240 | if (result < 0) { 241 | NTV2_MSG_ERROR("%s: *error* uart_register_driver failed code %d\n", 242 | ntv2_mod->name, result); 243 | return result; 244 | } 245 | ntv2_mod->uart_driver = &ntv2_uart_driver; 246 | 247 | /* register character driver */ 248 | result = alloc_chrdev_region(&ntv2_mod->cdev_number, 0, ntv2_mod->cdev_max, ntv2_mod->cdev_name); 249 | if (result < 0) { 250 | NTV2_MSG_ERROR("%s: *error* alloc_chrdev_region failed code %d\n", 251 | ntv2_mod->name, result); 252 | return result; 253 | } 254 | 255 | /* probe the devices */ 256 | result = pci_register_driver(&ntv2_pci_driver); 257 | if (result < 0) { 258 | NTV2_MSG_ERROR("%s: *error* pci_register_driver failed code %d\n", 259 | ntv2_mod->name, result); 260 | uart_unregister_driver(&ntv2_uart_driver); 261 | return result; 262 | } 263 | if (atomic_read(&ntv2_mod->device_index) == 0) 264 | NTV2_MSG_INFO("%s: no ntv2 boards found\n", ntv2_mod->name); 265 | 266 | NTV2_MSG_INFO("%s: module init complete\n", ntv2_mod->name); 267 | 268 | return 0; 269 | } 270 | 271 | static void __exit ntv2_module_exit(void) 272 | { 273 | struct ntv2_module *ntv2_mod = ntv2_module_info(); 274 | 275 | NTV2_MSG_INFO("%s: module exit start\n", ntv2_mod->name); 276 | 277 | pci_unregister_driver(&ntv2_pci_driver); 278 | unregister_chrdev_region(ntv2_mod->cdev_number, ntv2_mod->cdev_max); 279 | uart_unregister_driver(&ntv2_uart_driver); 280 | ntv2_module_release(); 281 | 282 | NTV2_MSG_INFO("%s: module exit complete\n", ntv2_mod->name); 283 | } 284 | 285 | module_init(ntv2_module_init); 286 | module_exit(ntv2_module_exit); 287 | -------------------------------------------------------------------------------- /driver/ntv2_xlxreg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 Xilinx PCI register constants 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_XLXREG_H 21 | #define NTV2_XLXREG_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | /* xilinx target register space id and sizes */ 26 | NTV2_CON(ntv2_xlxdma_con_target_size, 0x0400); 27 | NTV2_CON(ntv2_xlxdma_con_channel_size, 0x0040); 28 | NTV2_CON(ntv2_xlxdma_con_subsystem_id, 0x01fc); 29 | 30 | /* xilinx subsystem target offsets */ 31 | NTV2_CON(ntv2_xlxdma_con_target_channel_s2c, 0x0); 32 | NTV2_CON(ntv2_xlxdma_con_target_channel_c2s, 0x1); 33 | NTV2_CON(ntv2_xlxdma_con_target_irq, 0x2); 34 | NTV2_CON(ntv2_xlxdma_con_target_config, 0x3); 35 | NTV2_CON(ntv2_xlxdma_con_target_sgdma_s2c, 0x4); 36 | NTV2_CON(ntv2_xlxdma_con_target_sgdma_c2s, 0x5); 37 | NTV2_CON(ntv2_xlxdma_con_target_sgdma_common, 0x6); 38 | NTV2_CON(ntv2_xlxdma_con_target_msix, 0x8); 39 | 40 | /* xilinx s2c identifier register */ 41 | NTV2_REG(ntv2_xlxdma_reg_chn_identifier, 0x0000, 0x0040, 0x0080, 0x00c0, 0x0400, 0x0440, 0x0480, 0x04c0); 42 | NTV2_FLD(ntv2_xlxdma_fld_chn_version, 8, 0); 43 | NTV2_FLD(ntv2_xlxdma_fld_chn_id_target, 4, 8); 44 | NTV2_FLD(ntv2_xlxdma_fld_chn_stream_interface, 1, 15); 45 | NTV2_FLD(ntv2_xlxdma_fld_chn_target, 4, 16); 46 | NTV2_FLD(ntv2_xlxdma_fld_chn_subsystem_id, 12, 20); 47 | 48 | /* xilinx s2c control registers */ 49 | NTV2_REG(ntv2_xlxdma_reg_chn_control, 0x0001, 0x0041, 0x0081, 0x00c1, 0x0401, 0x0441, 0x0481, 0x04c1); 50 | NTV2_REG(ntv2_xlxdma_reg_chn_control_w1s, 0x0002, 0x0042, 0x0082, 0x00c2, 0x0402, 0x0442, 0x0482, 0x04c2); 51 | NTV2_REG(ntv2_xlxdma_reg_chn_control_w1c, 0x0003, 0x0043, 0x0083, 0x00c3, 0x0403, 0x0443, 0x0483, 0x04c3); 52 | NTV2_FLD(ntv2_xlxdma_fld_chn_run, 1, 0); 53 | NTV2_FLD(ntv2_xlxdma_fld_chn_desc_stop, 1, 1); 54 | NTV2_FLD(ntv2_xlxdma_fld_chn_desc_complete, 1, 2); 55 | NTV2_FLD(ntv2_xlxdma_fld_chn_align_mismatch, 1, 3); 56 | NTV2_FLD(ntv2_xlxdma_fld_chn_magic_stop, 1, 4); 57 | NTV2_FLD(ntv2_xlxdma_fld_chn_invalid_length, 1, 5); 58 | NTV2_FLD(ntv2_xlxdma_fld_chn_idle_stop, 1, 6); 59 | NTV2_FLD(ntv2_xlxdma_fld_chn_read_error, 5, 9); 60 | NTV2_FLD(ntv2_xlxdma_fld_chn_write_error, 5, 14); 61 | NTV2_FLD(ntv2_xlxdma_fld_chn_desc_error, 5, 19); 62 | NTV2_FLD(ntv2_xlxdma_fld_chn_non_inc_address_mode, 1, 25); 63 | NTV2_FLD(ntv2_xlxdma_fld_chn_poll_mode_write_enable, 1, 26); 64 | NTV2_FLD(ntv2_xlxdma_fld_chn_stream_write_disable, 1, 27); 65 | 66 | /* xilinx s2c status registers */ 67 | NTV2_REG(ntv2_xlxdma_reg_chn_status, 0x0010, 0x0050, 0x0090, 0x00d0, 0x0410, 0x0450, 0x0490, 0x04d0); 68 | NTV2_REG(ntv2_xlxdma_reg_chn_status_rc, 0x0011, 0x0051, 0x0091, 0x00d1, 0x0411, 0x0451, 0x0491, 0x04d1); 69 | 70 | /* xilinx s2c descriptor complete count register */ 71 | NTV2_REG(ntv2_xlxdma_reg_chn_desc_complete_count, 0x0012, 0x0052, 0x0092, 0x00d2, 0x0412, 0x0452, 0x0492, 0x04d2); 72 | 73 | /* xilinx s2c transfer alignment register */ 74 | NTV2_REG(ntv2_xlxdma_reg_chn_alignments, 0x0013, 0x0053, 0x0093, 0x00d3, 0x0413, 0x0453, 0x0493, 0x04d3); 75 | NTV2_FLD(ntv2_xlxdma_fld_chn_address_bits, 8, 0); 76 | NTV2_FLD(ntv2_xlxdma_fld_chn_transfer_alignment, 8, 8); 77 | NTV2_FLD(ntv2_xlxdma_fld_chn_address_alignment, 8, 16); 78 | 79 | /* xilinx s2c poll mode address registers */ 80 | NTV2_REG(ntv2_xlxdma_reg_chn_poll_mode_address_low, 0x0022, 0x0062, 0x00a2, 0x00e2, 0x0422, 0x0462, 0x04a2, 0x04e2); 81 | NTV2_REG(ntv2_xlxdma_reg_chn_poll_mode_address_high, 0x0023, 0x0063, 0x00a3, 0x00e3, 0x0423, 0x0463, 0x04a3, 0x04e3); 82 | 83 | /* xilinx s2c interrupt enable registers */ 84 | NTV2_REG(ntv2_xlxdma_reg_chn_interrupt_enable, 0x0024, 0x0064, 0x00a4, 0x00e4, 0x0424, 0x0464, 0x04a4, 0x04e4); 85 | NTV2_REG(ntv2_xlxdma_reg_chn_interrupt_enable_w1s, 0x0025, 0x0065, 0x00a5, 0x00e5, 0x0425, 0x0465, 0x04a5, 0x04e5); 86 | NTV2_REG(ntv2_xlxdma_reg_chn_interrupt_enable_w1c, 0x0026, 0x0066, 0x00a6, 0x00e6, 0x0426, 0x0466, 0x04a6, 0x04e6); 87 | 88 | /* xilinx s2c performance control register */ 89 | NTV2_REG(ntv2_xlxdma_reg_chn_perf_control, 0x0030, 0x0070, 0x00b0, 0x00f0, 0x0430, 0x0470, 0x04b0, 0x04f0); 90 | NTV2_FLD(ntv2_xlxdma_fld_chn_perf_auto, 1, 0); 91 | NTV2_FLD(ntv2_xlxdma_fld_chn_perf_clear, 1, 1); 92 | NTV2_FLD(ntv2_xlxdma_fld_chn_perf_run, 1, 2); 93 | 94 | /* xilinx s2c cycle count registers */ 95 | NTV2_REG(ntv2_xlxdma_reg_chn_perf_cycle_count_low, 0x0031, 0x0071, 0x00b1, 0x00f1, 0x0431, 0x0471, 0x04b1, 0x04f1); 96 | NTV2_REG(ntv2_xlxdma_reg_chn_perf_cycle_count_high, 0x0032, 0x0072, 0x00b2, 0x00f2, 0x0432, 0x0472, 0x04b2, 0x04f2); 97 | NTV2_FLD(ntv2_xlxdma_fld_chn_perf_cycle_count_bits, 10, 0); 98 | NTV2_FLD(ntv2_xlxdma_fld_chn_perf_cycle_count_maxed, 1, 16); 99 | 100 | /* xilinx s2c data count registers */ 101 | NTV2_REG(ntv2_xlxdma_reg_chn_perf_data_count_low, 0x0033, 0x0073, 0x00b3, 0x00f3, 0x0433, 0x0473, 0x04b3, 0x04f3); 102 | NTV2_REG(ntv2_xlxdma_reg_chn_perf_data_count_high, 0x0034, 0x0074, 0x00b4, 0x00f4, 0x0434, 0x0474, 0x04b4, 0x04f4); 103 | NTV2_FLD(ntv2_xlxdma_fld_chn_perf_data_count_bits, 10, 0); 104 | NTV2_FLD(ntv2_xlxdma_fld_chn_perf_data_count_maxed, 1, 16); 105 | 106 | /* xilinx irq identifier register */ 107 | NTV2_REG(ntv2_xlxdma_reg_irq_identifier, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800); 108 | 109 | /* xilinx irq user interrupt enable registers */ 110 | NTV2_REG(ntv2_xlxdma_reg_irq_usr_interrupt_enable, 0x0801, 0x0801, 0x0801, 0x0801, 0x0801, 0x0801, 0x0801, 0x0801); 111 | NTV2_REG(ntv2_xlxdma_reg_irq_usr_interrupt_enable_w1s, 0x0802, 0x0802, 0x0802, 0x0802, 0x0802, 0x0802, 0x0802, 0x0802); 112 | NTV2_REG(ntv2_xlxdma_reg_irq_usr_interrupt_enable_w1c, 0x0803, 0x0803, 0x0803, 0x0803, 0x0803, 0x0803, 0x0803, 0x0803); 113 | 114 | /* xilinx irq channel interrupt enable registers */ 115 | NTV2_REG(ntv2_xlxdma_reg_irq_chn_interrupt_enable, 0x0804, 0x0804, 0x0804, 0x0804, 0x0804, 0x0804, 0x0804, 0x0804); 116 | NTV2_REG(ntv2_xlxdma_reg_irq_chn_interrupt_enable_w1s, 0x0805, 0x0805, 0x0805, 0x0805, 0x0805, 0x0805, 0x0805, 0x0805); 117 | NTV2_REG(ntv2_xlxdma_reg_irq_chn_interrupt_enable_w1c, 0x0806, 0x0806, 0x0806, 0x0806, 0x0806, 0x0806, 0x0806, 0x0806); 118 | 119 | /* xilinx irq interrupt request registers */ 120 | NTV2_REG(ntv2_xlxdma_reg_irq_usr_interrupt_request, 0x0810, 0x0810, 0x0810, 0x0810, 0x0810, 0x0810, 0x0810, 0x0810); 121 | NTV2_REG(ntv2_xlxdma_reg_irq_chn_interrupt_request, 0x0811, 0x0811, 0x0811, 0x0811, 0x0811, 0x0811, 0x0811, 0x0811); 122 | 123 | /* xilinx irq interrupt pending event registers */ 124 | NTV2_REG(ntv2_xlxdma_reg_irq_usr_interrupt_pending, 0x0812, 0x0812, 0x0812, 0x0812, 0x0812, 0x0812, 0x0812, 0x0812); 125 | NTV2_REG(ntv2_xlxdma_reg_irq_chn_interrupt_pending, 0x0813, 0x0813, 0x0813, 0x0813, 0x0813, 0x0813, 0x0813, 0x0813); 126 | 127 | /* xilinx segment identifier register */ 128 | NTV2_REG(ntv2_xlxdma_reg_seg_identifier, 0x1000, 0x1040, 0x1080, 0x10c0, 0x1400, 0x1440, 0x1480, 0x14c0); 129 | 130 | /* xilinx segment descriptor address registers */ 131 | NTV2_REG(ntv2_xlxdma_reg_seg_desc_address_low, 0x1020, 0x1060, 0x10a0, 0x10e0, 0x1420, 0x1460, 0x14a0, 0x14e0); 132 | NTV2_REG(ntv2_xlxdma_reg_seg_desc_address_high, 0x1021, 0x1061, 0x10a1, 0x10e1, 0x1421, 0x1461, 0x14a1, 0x14e1); 133 | 134 | /* xilinx segment descriptor adjacent register */ 135 | NTV2_REG(ntv2_xlxdma_reg_seg_desc_adjacent, 0x1022, 0x1062, 0x10a2, 0x10e2, 0x1422, 0x1462, 0x14a2, 0x14e2); 136 | 137 | /* xilinx segment descriptor credits register */ 138 | NTV2_REG(ntv2_xlxdma_reg_seg_desc_credits, 0x1023, 0x1063, 0x10a3, 0x10e3, 0x1423, 0x1463, 0x14a3, 0x14e3); 139 | 140 | /* xilinx descriptor control parameter bit definitions */ 141 | NTV2_FLD(ntv2_xlxdma_fld_desc_control_stop, 1, 0); 142 | NTV2_FLD(ntv2_xlxdma_fld_desc_control_completion, 1, 1); 143 | NTV2_FLD(ntv2_xlxdma_fld_desc_control_eop, 1, 4); 144 | NTV2_FLD(ntv2_xlxdma_fld_desc_control_count, 5, 8); 145 | NTV2_FLD(ntv2_xlxdma_fld_desc_control_magic, 16, 16); 146 | 147 | /* xilinx descriptor control magic constant */ 148 | NTV2_CON(ntv2_xlxdma_con_desc_control_magic, 0xad4b); 149 | 150 | #endif 151 | -------------------------------------------------------------------------------- /driver/ntv2_features.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 device features 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_FEATURES_H 21 | #define NTV2_FEATURES_H 22 | 23 | #include "ntv2_common.h" 24 | 25 | enum ntv2_component { 26 | ntv2_component_unknown, 27 | ntv2_component_sdi, 28 | ntv2_component_hdmi, 29 | ntv2_component_csc, 30 | ntv2_component_video, 31 | ntv2_component_audio, 32 | ntv2_component_size, 33 | }; 34 | 35 | struct ntv2_video_config { 36 | bool capture; 37 | bool playback; 38 | }; 39 | 40 | struct ntv2_audio_config { 41 | bool capture; 42 | bool playback; 43 | u32 sample_rate; 44 | u32 num_channels; 45 | u32 sample_size; 46 | u32 ring_size; 47 | u32 ring_offset_samples; 48 | u32 sync_tolerance; 49 | }; 50 | 51 | struct ntv2_serial_config { 52 | u32 type; 53 | u32 fifo_size; 54 | }; 55 | 56 | struct ntv2_input_config { 57 | const char* name; 58 | enum ntv2_input_type type; 59 | enum ntv2_edid_type edid; 60 | struct v4l2_dv_timings_cap v4l2_timings_cap; 61 | u32 frame_flags; 62 | int reg_index; 63 | int input_index; 64 | int num_inputs; 65 | }; 66 | 67 | struct ntv2_source_config { 68 | const char* name; 69 | enum ntv2_input_type type; 70 | u32 audio_source; 71 | u32 num_channels; 72 | int reg_index; 73 | int input_index; 74 | int num_inputs; 75 | }; 76 | 77 | struct ntv2_widget_config { 78 | const char* name; 79 | int widget_index; 80 | int num_widgets; 81 | }; 82 | 83 | struct ntv2_features { 84 | int index; 85 | char name[NTV2_STRING_SIZE]; 86 | struct list_head list; 87 | struct ntv2_device *ntv2_dev; 88 | spinlock_t state_lock; 89 | 90 | u32 device_id; 91 | const char *device_name; 92 | const char *pcm_name; 93 | 94 | int num_video_channels; 95 | int num_audio_channels; 96 | int num_csc_channels; 97 | int num_sdi_inputs; 98 | int num_hdmi_inputs; 99 | int num_aes_inputs; 100 | int num_analog_inputs; 101 | int num_reference_inputs; 102 | int num_serial_ports; 103 | u32 frame_buffer_size; 104 | int req_line_interleave_channels; 105 | int req_sample_interleave_channels; 106 | int req_square_division_channels; 107 | 108 | struct ntv2_video_config *video_config[NTV2_MAX_CHANNELS]; 109 | struct ntv2_input_config *input_config[NTV2_MAX_CHANNELS][NTV2_MAX_INPUT_CONFIGS]; 110 | struct ntv2_widget_config *csc_config[NTV2_MAX_CHANNELS][NTV2_MAX_CSC_CONFIGS]; 111 | 112 | struct ntv2_audio_config *audio_config[NTV2_MAX_CHANNELS]; 113 | struct ntv2_source_config *source_config[NTV2_MAX_CHANNELS][NTV2_MAX_SOURCE_CONFIGS]; 114 | 115 | struct ntv2_video_format *video_formats[NTV2_MAX_VIDEO_FORMATS]; 116 | struct ntv2_pixel_format *pixel_formats[NTV2_MAX_PIXEL_FORMATS]; 117 | struct v4l2_dv_timings *v4l2_timings[NTV2_MAX_VIDEO_FORMATS]; 118 | 119 | unsigned long component_owner[ntv2_component_size][NTV2_MAX_CHANNELS]; 120 | 121 | struct ntv2_serial_config *serial_config[NTV2_MAX_CHANNELS]; 122 | enum ntv2_edid_type hdmi_edid[NTV2_MAX_CHANNELS]; 123 | }; 124 | 125 | 126 | struct ntv2_features *ntv2_features_open(struct ntv2_object *ntv2_obj, 127 | const char *name, int index); 128 | void ntv2_features_close(struct ntv2_features *features); 129 | 130 | int ntv2_features_configure(struct ntv2_features *features, u32 id); 131 | 132 | struct ntv2_video_config 133 | *ntv2_features_get_video_config(struct ntv2_features *features, 134 | int channel_index); 135 | 136 | struct ntv2_audio_config 137 | *ntv2_features_get_audio_config(struct ntv2_features *features, 138 | int channel_index); 139 | 140 | struct ntv2_input_config 141 | *ntv2_features_get_input_config(struct ntv2_features *features, 142 | int channel_index, 143 | int config_index); 144 | int ntv2_features_num_input_configs(struct ntv2_features *features, 145 | int channel_index); 146 | struct ntv2_input_config 147 | *ntv2_features_get_default_input_config(struct ntv2_features *features, 148 | int channel_index); 149 | 150 | struct ntv2_source_config 151 | *ntv2_features_get_source_config(struct ntv2_features *features, 152 | int channel_index, 153 | int source_index); 154 | int ntv2_features_num_source_configs(struct ntv2_features *features, 155 | int channel_index); 156 | struct ntv2_source_config 157 | *ntv2_features_get_default_source_config(struct ntv2_features *features, 158 | int channel_index, 159 | bool noauto); 160 | 161 | struct ntv2_pixel_format 162 | *ntv2_features_get_pixel_format(struct ntv2_features *features, 163 | int channel_index, 164 | int format_index); 165 | int ntv2_features_num_pixel_formats(struct ntv2_features *features, 166 | int channel_index); 167 | struct ntv2_pixel_format 168 | *ntv2_features_get_default_pixel_format(struct ntv2_features *features, 169 | int channel_index); 170 | 171 | struct ntv2_video_format 172 | *ntv2_features_get_video_format(struct ntv2_features *features, 173 | int channel_index, 174 | int format_index); 175 | int ntv2_features_num_video_formats(struct ntv2_features *features, 176 | int channel_index); 177 | struct ntv2_video_format 178 | *ntv2_features_get_default_video_format(struct ntv2_features *features, 179 | int channel_index); 180 | 181 | struct ntv2_source_config 182 | *ntv2_features_find_source_config(struct ntv2_features *features, 183 | int channel_index, 184 | enum ntv2_input_type input_type, 185 | int input_index); 186 | 187 | struct ntv2_widget_config 188 | *ntv2_features_find_csc_config(struct ntv2_features *features, 189 | int channel_index, int num_cscs); 190 | 191 | void ntv2_features_gen_input_format(struct ntv2_input_config *config, 192 | struct ntv2_video_format *vidf, 193 | struct ntv2_pixel_format *pixf, 194 | struct ntv2_input_format *inpf); 195 | 196 | void ntv2_features_gen_source_format(struct ntv2_source_config *config, 197 | struct ntv2_source_format *format); 198 | 199 | u32 ntv2_features_line_pitch(struct ntv2_pixel_format *format, u32 pixels); 200 | 201 | u32 ntv2_features_ntv2_frame_size(struct ntv2_video_format *vidf, 202 | struct ntv2_pixel_format *pixf); 203 | 204 | u32 ntv2_features_v4l2_frame_size(struct ntv2_video_format *vidf, 205 | struct ntv2_pixel_format *pixf); 206 | 207 | int ntv2_features_get_frame_range(struct ntv2_features *features, 208 | struct ntv2_video_format *vidf, 209 | struct ntv2_pixel_format *pixf, 210 | int index, 211 | u32 *first, 212 | u32 *last, 213 | u32 *size); 214 | 215 | u32 ntv2_features_get_audio_capture_address(struct ntv2_features *features, u32 index); 216 | u32 ntv2_features_get_audio_play_address(struct ntv2_features *features, u32 index); 217 | 218 | int ntv2_features_acquire_components(struct ntv2_features *features, enum ntv2_component com, 219 | int index, int num, unsigned long owner); 220 | int ntv2_features_release_components(struct ntv2_features *features, enum ntv2_component com, 221 | int index, int num, unsigned long owner); 222 | void ntv2_features_release_video_components(struct ntv2_features *features, unsigned long owner); 223 | void ntv2_features_release_audio_components(struct ntv2_features *features, unsigned long owner); 224 | 225 | bool ntv2_features_valid_dv_timings(struct ntv2_features *features, 226 | const struct v4l2_dv_timings *t, 227 | const struct v4l2_dv_timings_cap *cap); 228 | 229 | int ntv2_features_enum_dv_timings_cap(struct ntv2_features *features, 230 | struct v4l2_enum_dv_timings *t, 231 | const struct v4l2_dv_timings_cap *cap); 232 | 233 | bool ntv2_features_find_dv_timings_cap(struct ntv2_features *features, 234 | struct v4l2_dv_timings *t, 235 | const struct v4l2_dv_timings_cap *cap, 236 | unsigned pclock_delta); 237 | 238 | bool ntv2_features_match_dv_timings(const struct v4l2_dv_timings *measured, 239 | const struct v4l2_dv_timings *standard, 240 | unsigned pclock_delta); 241 | 242 | int ntv2_features_req_line_interleave_channels(struct ntv2_features *features); 243 | int ntv2_features_req_sample_interleave_channels(struct ntv2_features *features); 244 | int ntv2_features_req_square_division_channels(struct ntv2_features *features); 245 | 246 | enum ntv2_edid_type 247 | ntv2_features_hdmi_edid_type(struct ntv2_features *features, int index); 248 | 249 | #endif 250 | -------------------------------------------------------------------------------- /driver/ntv2_pci.c: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 generic pci interface 3 | * 4 | * Copyright 2018 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #include "ntv2_pci.h" 21 | #include "ntv2_register.h" 22 | #include "ntv2_nwldma.h" 23 | #include "ntv2_xlxdma.h" 24 | 25 | 26 | static struct ntv2_nwldma* ntv2_pci_nwl_config(struct ntv2_pci *ntv2_pci, int index); 27 | static struct ntv2_xlxdma* ntv2_pci_xlx_config(struct ntv2_pci *ntv2_pci, int index); 28 | 29 | 30 | struct ntv2_pci *ntv2_pci_open(struct ntv2_object *ntv2_obj, 31 | const char *name, int index) 32 | { 33 | struct ntv2_pci *ntv2_pci; 34 | 35 | if (ntv2_obj == NULL) 36 | return NULL; 37 | 38 | ntv2_pci = kzalloc(sizeof(struct ntv2_pci), GFP_KERNEL); 39 | if (ntv2_pci == NULL) { 40 | NTV2_MSG_ERROR("%s: ntv2_pci instance memory allocation failed\n", ntv2_obj->name); 41 | return NULL; 42 | } 43 | 44 | ntv2_pci->index = index; 45 | snprintf(ntv2_pci->name, NTV2_STRING_SIZE, "%s-%s%d", ntv2_obj->name, name, index); 46 | INIT_LIST_HEAD(&ntv2_pci->list); 47 | ntv2_pci->ntv2_dev = ntv2_obj->ntv2_dev; 48 | 49 | spin_lock_init(&ntv2_pci->state_lock); 50 | 51 | NTV2_MSG_PCI_INFO("%s: open ntv2_pci\n", ntv2_pci->name); 52 | 53 | return ntv2_pci; 54 | } 55 | 56 | void ntv2_pci_close(struct ntv2_pci *ntv2_pci) 57 | { 58 | int i; 59 | 60 | if (ntv2_pci == NULL) 61 | return; 62 | 63 | NTV2_MSG_PCI_INFO("%s: close ntv2_pci\n", ntv2_pci->name); 64 | 65 | /* close all dma engines */ 66 | switch (ntv2_pci->pci_type) 67 | { 68 | case ntv2_pci_type_nwl: 69 | for (i = 0; i < NTV2_MAX_DMA_ENGINES; i++) 70 | { 71 | if (ntv2_pci->nwl_engine[i] != NULL) { 72 | ntv2_nwldma_close(ntv2_pci->nwl_engine[i]); 73 | ntv2_pci->nwl_engine[i] = NULL; 74 | } 75 | } 76 | break; 77 | case ntv2_pci_type_xlx: 78 | default: 79 | break; 80 | } 81 | 82 | kfree(ntv2_pci); 83 | } 84 | 85 | int ntv2_pci_configure(struct ntv2_pci *ntv2_pci, 86 | enum ntv2_pci_type pci_type, 87 | struct ntv2_register *pci_reg) 88 | { 89 | if ((ntv2_pci == NULL) || (pci_reg == NULL)) 90 | return -EPERM; 91 | 92 | NTV2_MSG_PCI_INFO("%s: configure pci interrupts and dma engines\n", ntv2_pci->name); 93 | 94 | ntv2_pci->pci_type = pci_type; 95 | ntv2_pci->pci_reg = pci_reg; 96 | 97 | /* get dma engines */ 98 | switch (ntv2_pci->pci_type) 99 | { 100 | case ntv2_pci_type_nwl: 101 | ntv2_nwldma_interrupt_disable(pci_reg); 102 | ntv2_pci->nwl_engine[0] = ntv2_pci_nwl_config(ntv2_pci, 4); 103 | if (ntv2_pci->nwl_engine[0] == NULL) 104 | return -EPERM; 105 | break; 106 | case ntv2_pci_type_xlx: 107 | ntv2_xlxdma_interrupt_disable(pci_reg); 108 | ntv2_pci->xlx_engine[0] = ntv2_pci_xlx_config(ntv2_pci, 4); 109 | if (ntv2_pci->xlx_engine[0] == NULL) 110 | return -EPERM; 111 | default: 112 | break; 113 | } 114 | 115 | return 0; 116 | } 117 | 118 | int ntv2_pci_enable(struct ntv2_pci *ntv2_pci) 119 | { 120 | unsigned long flags; 121 | int i; 122 | 123 | if ((ntv2_pci == NULL) || (ntv2_pci->pci_reg == NULL)) 124 | return -EPERM; 125 | 126 | if (ntv2_pci->pci_state == ntv2_task_state_enable) 127 | return 0; 128 | 129 | NTV2_MSG_PCI_INFO("%s: enable interrupts\n", ntv2_pci->name); 130 | 131 | spin_lock_irqsave(&ntv2_pci->state_lock, flags); 132 | ntv2_pci->pci_state = ntv2_task_state_enable; 133 | 134 | /* enable interrupts and dma engines */ 135 | switch (ntv2_pci->pci_type) 136 | { 137 | case ntv2_pci_type_nwl: 138 | ntv2_nwldma_interrupt_enable(ntv2_pci->pci_reg); 139 | for (i = 0; i < NTV2_MAX_DMA_ENGINES; i++) 140 | { 141 | if (ntv2_pci->nwl_engine[i] != NULL) { 142 | ntv2_nwldma_enable(ntv2_pci->nwl_engine[i]); 143 | } 144 | } 145 | break; 146 | case ntv2_pci_type_xlx: 147 | ntv2_xlxdma_interrupt_enable(ntv2_pci->pci_reg); 148 | for (i = 0; i < NTV2_MAX_DMA_ENGINES; i++) 149 | { 150 | if (ntv2_pci->xlx_engine[i] != NULL) { 151 | ntv2_xlxdma_enable(ntv2_pci->xlx_engine[i]); 152 | } 153 | } 154 | break; 155 | default: 156 | break; 157 | } 158 | 159 | spin_unlock_irqrestore(&ntv2_pci->state_lock, flags); 160 | 161 | return 0; 162 | } 163 | 164 | int ntv2_pci_disable(struct ntv2_pci *ntv2_pci) 165 | { 166 | unsigned long flags; 167 | int i; 168 | 169 | if ((ntv2_pci == NULL) || (ntv2_pci->pci_reg == NULL)) 170 | return -EPERM; 171 | 172 | if (ntv2_pci->pci_state == ntv2_task_state_disable) 173 | return 0; 174 | 175 | NTV2_MSG_PCI_INFO("%s: disable interrupts\n", ntv2_pci->name); 176 | 177 | spin_lock_irqsave(&ntv2_pci->state_lock, flags); 178 | 179 | /* disable dma engines and interrupts */ 180 | switch (ntv2_pci->pci_type) 181 | { 182 | case ntv2_pci_type_nwl: 183 | for (i = 0; i < NTV2_MAX_DMA_ENGINES; i++) 184 | { 185 | if (ntv2_pci->nwl_engine[i] != NULL) { 186 | ntv2_nwldma_disable(ntv2_pci->nwl_engine[i]); 187 | } 188 | } 189 | ntv2_nwldma_interrupt_disable(ntv2_pci->pci_reg); 190 | break; 191 | case ntv2_pci_type_xlx: 192 | for (i = 0; i < NTV2_MAX_DMA_ENGINES; i++) 193 | { 194 | if (ntv2_pci->xlx_engine[i] != NULL) { 195 | ntv2_xlxdma_disable(ntv2_pci->xlx_engine[i]); 196 | } 197 | } 198 | ntv2_xlxdma_interrupt_disable(ntv2_pci->pci_reg); 199 | break; 200 | default: 201 | break; 202 | } 203 | 204 | ntv2_pci->pci_state = ntv2_task_state_disable; 205 | 206 | spin_unlock_irqrestore(&ntv2_pci->state_lock, flags); 207 | 208 | return 0; 209 | } 210 | 211 | int ntv2_pci_transfer(struct ntv2_pci *ntv2_pci, 212 | struct ntv2_transfer *ntv2_trn) 213 | { 214 | unsigned long flags; 215 | int result = -EPERM; 216 | 217 | if (ntv2_pci == NULL) 218 | return -EPERM; 219 | 220 | spin_lock_irqsave(&ntv2_pci->state_lock, flags); 221 | 222 | if (ntv2_pci->pci_state == ntv2_task_state_disable) { 223 | spin_unlock_irqrestore(&ntv2_pci->state_lock, flags); 224 | return 0; 225 | } 226 | 227 | /* pass transfer to proper dma engine */ 228 | switch (ntv2_pci->pci_type) 229 | { 230 | case ntv2_pci_type_nwl: 231 | if (ntv2_pci->nwl_engine[0] != NULL) 232 | result = ntv2_nwldma_transfer(ntv2_pci->nwl_engine[0], ntv2_trn); 233 | break; 234 | case ntv2_pci_type_xlx: 235 | if (ntv2_pci->xlx_engine[0] != NULL) 236 | result = ntv2_xlxdma_transfer(ntv2_pci->xlx_engine[0], ntv2_trn); 237 | break; 238 | default: 239 | break; 240 | } 241 | 242 | spin_unlock_irqrestore(&ntv2_pci->state_lock, flags); 243 | 244 | return result; 245 | } 246 | 247 | int ntv2_pci_interrupt(struct ntv2_pci *ntv2_pci) 248 | { 249 | int result = IRQ_NONE; 250 | int res; 251 | int i; 252 | 253 | if (ntv2_pci == NULL) 254 | return IRQ_NONE; 255 | 256 | /* pass interrupt to dma engines */ 257 | switch (ntv2_pci->pci_type) 258 | { 259 | case ntv2_pci_type_nwl: 260 | for (i = 0; i < NTV2_MAX_DMA_ENGINES; i++) 261 | { 262 | if (ntv2_pci->nwl_engine[i] != NULL) { 263 | res = ntv2_nwldma_interrupt(ntv2_pci->nwl_engine[i]); 264 | if (res == IRQ_HANDLED) 265 | result = IRQ_HANDLED; 266 | } 267 | } 268 | break; 269 | case ntv2_pci_type_xlx: 270 | for (i = 0; i < NTV2_MAX_DMA_ENGINES; i++) 271 | { 272 | if (ntv2_pci->xlx_engine[i] != NULL) { 273 | res = ntv2_xlxdma_interrupt(ntv2_pci->xlx_engine[i]); 274 | if (res == IRQ_HANDLED) 275 | result = IRQ_HANDLED; 276 | } 277 | } 278 | break; 279 | default: 280 | break; 281 | } 282 | 283 | return result; 284 | } 285 | 286 | static struct ntv2_nwldma* ntv2_pci_nwl_config(struct ntv2_pci *ntv2_pci, int index) 287 | { 288 | struct ntv2_nwldma *ntv2_nwl; 289 | int result; 290 | 291 | /* open and configure nwl dma engine */ 292 | ntv2_nwl = ntv2_nwldma_open((struct ntv2_object*)ntv2_pci, "nwd", index); 293 | if (ntv2_nwl == NULL) 294 | return NULL; 295 | 296 | result = ntv2_nwldma_configure(ntv2_nwl, ntv2_pci->pci_reg); 297 | if (result != 0) { 298 | ntv2_nwldma_close(ntv2_nwl); 299 | return NULL; 300 | } 301 | 302 | result = ntv2_nwldma_enable(ntv2_nwl); 303 | if (result != 0) { 304 | ntv2_nwldma_close(ntv2_nwl); 305 | return NULL; 306 | } 307 | 308 | return ntv2_nwl; 309 | } 310 | 311 | static struct ntv2_xlxdma* ntv2_pci_xlx_config(struct ntv2_pci *ntv2_pci, int index) 312 | { 313 | struct ntv2_xlxdma *ntv2_xlx; 314 | int result; 315 | 316 | /* open and configure xlx dma engine */ 317 | ntv2_xlx = ntv2_xlxdma_open((struct ntv2_object*)ntv2_pci, "xlx", index); 318 | if (ntv2_xlx == NULL) 319 | return NULL; 320 | 321 | result = ntv2_xlxdma_configure(ntv2_xlx, ntv2_pci->pci_reg); 322 | if (result != 0) { 323 | ntv2_xlxdma_close(ntv2_xlx); 324 | return NULL; 325 | } 326 | 327 | result = ntv2_xlxdma_enable(ntv2_xlx); 328 | if (result != 0) { 329 | ntv2_xlxdma_close(ntv2_xlx); 330 | return NULL; 331 | } 332 | 333 | return ntv2_xlx; 334 | } 335 | 336 | -------------------------------------------------------------------------------- /driver/ntv2_timecode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 timecode utility 3 | * 4 | * Copyright 2018 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #include "ntv2_timecode.h" 21 | 22 | 23 | #define NTV2_TIMECODE_DROP_MASK_LOW 0x00000400 24 | #define NTV2_TIMECODE_COLOR_MASK_LOW 0x00000800 25 | #define NTV2_TIMECODE_FIELD_MASK_LOW 0x08000000 26 | #define NTV2_TIMECODE_BGF0_MASK_HIGH 0x00000800 27 | #define NTV2_TIMECODE_BGF1_MASK_HIGH 0x04000000 28 | #define NTV2_TIMECODE_BGF2_MASK_HIGH 0x08000000 29 | 30 | #define NTV2_TIMECODE_25_COLOR_MASK_LOW 0x00000800 31 | #define NTV2_TIMECODE_25_FIELD_MASK_HIGH 0x08000000 32 | #define NTV2_TIMECODE_25_BGF0_MASK_LOW 0x08000000 33 | #define NTV2_TIMECODE_25_BGF1_MASK_HIGH 0x04000000 34 | #define NTV2_TIMECODE_25_BGF2_MASK_HIGH 0x00000800 35 | 36 | 37 | bool ntv2_timecode_compare_packed(struct ntv2_timecode_packed *tca, 38 | struct ntv2_timecode_packed *tcb, 39 | bool time_bits, bool user_bits) 40 | { 41 | u32 mask = 0; 42 | 43 | if ((tca == NULL) || (tcb == NULL)) 44 | return false; 45 | 46 | if (time_bits) mask |= 0x0f0f0f0f; 47 | if (user_bits) mask |= 0xf0f0f0f0; 48 | 49 | if (((tca->timecode_low & mask) == (tcb->timecode_low & mask)) && 50 | ((tca->timecode_high & mask) == (tcb->timecode_high & mask))) 51 | return true; 52 | 53 | return false; 54 | } 55 | 56 | bool ntv2_timecode_compare_data(struct ntv2_timecode_data *tca, 57 | struct ntv2_timecode_data *tcb, 58 | bool time_bits, bool user_bits, bool field) 59 | { 60 | if ((tca == NULL) || (tcb == NULL)) 61 | return false; 62 | 63 | if (time_bits && 64 | ((tca->frames != tcb->frames) || 65 | (tca->seconds != tcb->seconds) || 66 | (tca->minutes != tcb->minutes) || 67 | (tca->hours != tcb->hours) || 68 | (tca->drop_frame != tcb->drop_frame))) 69 | return false; 70 | 71 | if (user_bits && (tca->user_bits != tcb->user_bits)) 72 | return false; 73 | 74 | if (field && (tca->field != tcb->field)) 75 | return false; 76 | 77 | return true; 78 | } 79 | 80 | void ntv2_timecode_copy_data(struct ntv2_timecode_data *dst, 81 | struct ntv2_timecode_data *src, 82 | bool time_bits, bool user_bits, bool field) 83 | { 84 | if ((dst == NULL) || (src == NULL)) 85 | return; 86 | 87 | if (time_bits) { 88 | dst->frames = src->frames; 89 | dst->seconds = src->seconds; 90 | dst->minutes = src->minutes; 91 | dst->hours = src->hours; 92 | dst->drop_frame = src->drop_frame; 93 | } 94 | 95 | if (user_bits) { 96 | dst->user_bits = src->user_bits; 97 | } 98 | 99 | if (field) { 100 | dst->field = src->field; 101 | } 102 | 103 | return; 104 | } 105 | 106 | void ntv2_timecode_unpack(struct ntv2_timecode_data *data, 107 | struct ntv2_timecode_packed *pack, 108 | u32 fps, bool field) 109 | { 110 | if ((data == NULL) || (pack == NULL)) 111 | return; 112 | 113 | data->frames = (pack->timecode_low & 0x0000000f); 114 | data->user_bits = (pack->timecode_low & 0x000000f0) >> 4; /* >>4<<0 */ 115 | data->frames += ((pack->timecode_low & 0x00000300) >> 8) * 10; 116 | data->user_bits |= (pack->timecode_low & 0x0000f000) >> 8; /* >>12<<4 */ 117 | data->seconds = (pack->timecode_low & 0x000f0000) >> 16; 118 | data->user_bits |= (pack->timecode_low & 0x00f00000) >> 12; /* >>20<<8 */ 119 | data->seconds += ((pack->timecode_low & 0x07000000) >> 24) * 10; 120 | data->user_bits |= (pack->timecode_low & 0xf0000000) >> 16; /* >>28<<12 */ 121 | 122 | data->minutes = (pack->timecode_high & 0x0000000f) >> 0; 123 | data->user_bits |= (pack->timecode_high & 0x000000f0) << 12; /* >>4<<16 */ 124 | data->minutes += ((pack->timecode_high & 0x00000700) >> 8) * 10; 125 | data->user_bits |= (pack->timecode_high & 0x0000f000) << 8; /* >>12<<20 */ 126 | data->hours = (pack->timecode_high & 0x000f0000) >> 16; 127 | data->user_bits |= (pack->timecode_high & 0x00f00000) << 4; /* >>20<<24 */ 128 | data->hours += ((pack->timecode_high & 0x03000000) >> 24) * 10; 129 | data->user_bits |= (pack->timecode_high & 0xf0000000); /* >>28<<28 */ 130 | 131 | data->drop_frame = false; 132 | data->field = false; 133 | 134 | if (fps == 30) { 135 | data->drop_frame = (pack->timecode_low & NTV2_TIMECODE_DROP_MASK_LOW) != 0; 136 | } 137 | if (field) { 138 | if (fps == 25) { 139 | data->field = (pack->timecode_high & NTV2_TIMECODE_25_FIELD_MASK_HIGH) != 0; 140 | } else { 141 | data->field = (pack->timecode_low & NTV2_TIMECODE_FIELD_MASK_LOW) != 0; 142 | } 143 | } 144 | 145 | return; 146 | } 147 | 148 | void ntv2_timecode_pack(struct ntv2_timecode_data *data, 149 | struct ntv2_timecode_packed *pack, 150 | u32 fps, bool field) 151 | { 152 | if ((data == NULL) || (pack == NULL)) 153 | return; 154 | 155 | pack->timecode_low = ((data->frames % 10) & 0xf) << 0; 156 | pack->timecode_low |= (data->user_bits & 0x0000000f) << 4; /* >>0<<4 */ 157 | pack->timecode_low |= ((data->frames/10) & 0x3) << 8; 158 | pack->timecode_low |= (data->user_bits & 0x000000f0) << 8; /* >>4<<12 */ 159 | pack->timecode_low |= ((data->seconds % 10) & 0xf) << 16; 160 | pack->timecode_low |= (data->user_bits & 0x00000f00) << 12; /* >>8<<20 */ 161 | pack->timecode_low |= ((data->seconds/10) & 7) << 24; 162 | pack->timecode_low |= (data->user_bits & 0x0000f000) << 16; /* >>12<<28 */ 163 | 164 | pack->timecode_high = ((data->minutes % 10) & 0xf) << 0; 165 | pack->timecode_high |= (data->user_bits & 0x000f0000)>>12; /* >>16<<4 */ 166 | pack->timecode_high |= ((data->minutes/10) & 0x7) << 8; 167 | pack->timecode_high |= (data->user_bits & 0x00f00000)>>8; /* >>20<<12 */ 168 | pack->timecode_high |= ((data->hours % 10) & 0xf) << 16; 169 | pack->timecode_high |= (data->user_bits & 0x0f000000)>>4; /* >>24<<20 */ 170 | pack->timecode_high |= ((data->hours/10) & 3) << 24; 171 | pack->timecode_high |= (data->user_bits & 0xf0000000); /* >>28<<28 */ 172 | 173 | if (fps == 30) { 174 | if (data->drop_frame) 175 | pack->timecode_low |= NTV2_TIMECODE_DROP_MASK_LOW; 176 | } 177 | if (field && data->field) { 178 | if (fps == 25) { 179 | pack->timecode_high |= NTV2_TIMECODE_25_FIELD_MASK_HIGH; 180 | } else { 181 | pack->timecode_low |= NTV2_TIMECODE_FIELD_MASK_LOW; 182 | } 183 | } 184 | 185 | return; 186 | } 187 | 188 | void ntv2_timecode_offset(struct ntv2_timecode_data *data, u32 fps, bool field, int count) 189 | { 190 | int i; 191 | bool dec = false; 192 | 193 | if ((data == NULL) || (count == 0)) 194 | return; 195 | 196 | if (count < 0) { 197 | dec = true; 198 | count = -count; 199 | } 200 | 201 | for (i = 0; i < count; i++) { 202 | if (dec) { 203 | ntv2_timecode_decrement(data, fps, field); 204 | } else { 205 | ntv2_timecode_increment(data, fps, field); 206 | } 207 | } 208 | 209 | return; 210 | } 211 | 212 | void ntv2_timecode_increment(struct ntv2_timecode_data *data, u32 fps, bool field) 213 | { 214 | int hours; 215 | int minutes; 216 | int seconds; 217 | int frames; 218 | 219 | if (data == NULL) 220 | return; 221 | 222 | hours = (int)data->hours; 223 | minutes = (int)data->minutes; 224 | seconds = (int)data->seconds; 225 | frames = (int)data->frames; 226 | 227 | if (fps == 0) 228 | return; 229 | 230 | if (field) { 231 | if (!data->field) { 232 | data->field = true; 233 | return; 234 | } 235 | data->field = false; 236 | } 237 | 238 | frames++; 239 | if (frames == (int)fps) { frames = 0; seconds++; } 240 | if (seconds == 60) { seconds = 0; minutes++; } 241 | if (minutes == 60) { minutes = 0; hours++; } 242 | if (data->drop_frame && (fps == 30) && 243 | ((minutes % 10) != 0) && 244 | (seconds == 0) && 245 | (frames == 0)) frames = 2; 246 | if (hours == 24) hours = 0; 247 | 248 | data->hours = (u32)hours; 249 | data->minutes = (u32)minutes; 250 | data->seconds = (u32)seconds; 251 | data->frames = (u32)frames; 252 | 253 | return; 254 | } 255 | 256 | void ntv2_timecode_decrement(struct ntv2_timecode_data *data, u32 fps, bool field) 257 | { 258 | int hours; 259 | int minutes; 260 | int seconds; 261 | int frames; 262 | 263 | if (data == NULL) 264 | return; 265 | 266 | hours = (int)data->hours; 267 | minutes = (int)data->minutes; 268 | seconds = (int)data->seconds; 269 | frames = (int)data->frames; 270 | 271 | if (fps == 0) 272 | return; 273 | 274 | if (field) { 275 | if (data->field) { 276 | data->field = false; 277 | return; 278 | } 279 | data->field = true; 280 | } 281 | 282 | if (data->drop_frame && (fps == 30) && 283 | ((minutes % 10) != 0) && 284 | (seconds == 0) && 285 | (frames == 2)) frames = 0; 286 | frames--; 287 | if (frames == -1) { frames = (int)fps - 1; seconds--; } 288 | if (seconds == -1) { seconds = 59; minutes--; } 289 | if (minutes == -1) { minutes = 59; hours--; } 290 | if (hours == -1) hours = 23; 291 | 292 | data->hours = (u32)hours; 293 | data->minutes = (u32)minutes; 294 | data->seconds = (u32)seconds; 295 | data->frames = (u32)frames; 296 | 297 | return; 298 | } 299 | 300 | -------------------------------------------------------------------------------- /driver/ntv2_konai2c.c: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 I2C register interface 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #include "ntv2_konai2c.h" 21 | #include "ntv2_konareg.h" 22 | #include "ntv2_register.h" 23 | 24 | #define NTV2_BUSY_TIMEOUT 10000 25 | #define NTV2_WRITE_TIMEOUT 2000 26 | #define NTV2_WAIT_TIME_MIN 500 27 | #define NTV2_WAIT_TIME_MAX 1000 28 | #define NTV2_READ_TIMEOUT 200000 29 | #define NTV2_READ_TIME_MIN 5000 30 | #define NTV2_READ_TIME_MAX 10000 31 | #define NTV2_RESET_TIME_MIN 1000 32 | #define NTV2_RESET_TIME_MAX 10000 33 | 34 | static const u8 ntv2_subaddress_all = 0xff; 35 | 36 | static int ntv2_konai2c_wait_for_busy(struct ntv2_konai2c *ntv2_i2c, u32 timeout); 37 | static int ntv2_konai2c_wait_for_write(struct ntv2_konai2c *ntv2_i2c, u32 timeout); 38 | static int ntv2_konai2c_wait_for_read(struct ntv2_konai2c *ntv2_i2c, u32 timeout); 39 | static void ntv2_konai2c_reset(struct ntv2_konai2c *ntv2_i2c); 40 | 41 | struct ntv2_konai2c *ntv2_konai2c_open(struct ntv2_object *ntv2_obj, 42 | const char *name, int index) 43 | { 44 | struct ntv2_konai2c *ntv2_i2c = NULL; 45 | 46 | ntv2_i2c = kzalloc(sizeof(struct ntv2_konai2c), GFP_KERNEL); 47 | if (ntv2_i2c == NULL) { 48 | NTV2_MSG_ERROR("%s: ntv2_konai2c instance memory allocation failed\n", ntv2_obj->name); 49 | return NULL; 50 | } 51 | 52 | ntv2_i2c->index = index; 53 | snprintf(ntv2_i2c->name, NTV2_STRING_SIZE, "%s-%s%d", ntv2_obj->name, name, index); 54 | INIT_LIST_HEAD(&ntv2_i2c->list); 55 | ntv2_i2c->ntv2_dev = ntv2_obj->ntv2_dev; 56 | 57 | return ntv2_i2c; 58 | } 59 | 60 | void ntv2_konai2c_close(struct ntv2_konai2c *ntv2_i2c) 61 | { 62 | if (ntv2_i2c == NULL) 63 | return; 64 | 65 | memset(ntv2_i2c, 0, sizeof(struct ntv2_konai2c)); 66 | kfree(ntv2_i2c); 67 | } 68 | 69 | int ntv2_konai2c_configure(struct ntv2_konai2c *ntv2_i2c, 70 | struct ntv2_register *ntv2_reg, 71 | u32 control, 72 | u32 data) 73 | { 74 | if (ntv2_i2c == NULL) 75 | return -EPERM; 76 | 77 | NTV2_MSG_KONAI2C_INFO("%s: configure konai2c io\n", ntv2_i2c->name); 78 | 79 | if (ntv2_reg == NULL) { 80 | NTV2_MSG_KONAI2C_ERROR("%s: *error* bad configuration\n", ntv2_i2c->name); 81 | return -EPERM; 82 | } 83 | 84 | ntv2_i2c->kona_reg = ntv2_reg; 85 | ntv2_i2c->kona_control = control; 86 | ntv2_i2c->kona_data = data; 87 | 88 | return 0; 89 | } 90 | 91 | void ntv2_konai2c_set_device(struct ntv2_konai2c *ntv2_i2c, u8 device) 92 | { 93 | u32 val; 94 | 95 | if (ntv2_i2c == NULL) 96 | return; 97 | 98 | ntv2_i2c->i2c_device = device; 99 | 100 | val = NTV2_FLD_SET(ntv2_kona_fld_hdmiin_device_address, ntv2_i2c->i2c_device); 101 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_read_disable, 1); 102 | ntv2_register_write(ntv2_i2c->kona_reg, ntv2_i2c->kona_control, val); 103 | } 104 | 105 | u8 ntv2_konai2c_get_device(struct ntv2_konai2c *ntv2_i2c) 106 | { 107 | if (ntv2_i2c == NULL) 108 | return 0; 109 | 110 | return ntv2_i2c->i2c_device; 111 | } 112 | 113 | int ntv2_konai2c_write(struct ntv2_konai2c *ntv2_i2c, u8 address, u8 data) 114 | { 115 | u32 val; 116 | int res; 117 | 118 | if (ntv2_i2c == NULL) 119 | return -EPERM; 120 | 121 | NTV2_MSG_KONAI2C_WRITE("%s: write dev %02x add %02x data %02x\n", 122 | ntv2_i2c->name, ntv2_i2c->i2c_device, address, data); 123 | 124 | res = ntv2_konai2c_wait_for_busy(ntv2_i2c, NTV2_BUSY_TIMEOUT); 125 | if (res < 0) 126 | return res; 127 | 128 | val = NTV2_FLD_SET(ntv2_kona_fld_hdmiin_device_address, ntv2_i2c->i2c_device); 129 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_subaddress, address); 130 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_read_disable, 1); 131 | ntv2_register_write(ntv2_i2c->kona_reg, ntv2_i2c->kona_control, val); 132 | 133 | val = NTV2_FLD_SET(ntv2_kona_fld_hdmiin_data_out, data); 134 | ntv2_register_write(ntv2_i2c->kona_reg, ntv2_i2c->kona_data, val); 135 | 136 | res = ntv2_konai2c_wait_for_write(ntv2_i2c, NTV2_WRITE_TIMEOUT); 137 | if (res < 0) 138 | return res; 139 | 140 | return 0; 141 | } 142 | 143 | int ntv2_konai2c_cache_update(struct ntv2_konai2c *ntv2_i2c) 144 | { 145 | u32 val; 146 | int res; 147 | 148 | if (ntv2_i2c == NULL) 149 | return -EPERM; 150 | 151 | NTV2_MSG_KONAI2C_READ("%s: update device %02x read cache\n", 152 | ntv2_i2c->name, ntv2_i2c->i2c_device); 153 | 154 | res = ntv2_konai2c_wait_for_busy(ntv2_i2c, NTV2_BUSY_TIMEOUT); 155 | if (res < 0) 156 | return res; 157 | 158 | /* enable i2c reads */ 159 | val = NTV2_FLD_SET(ntv2_kona_fld_hdmiin_device_address, ntv2_i2c->i2c_device); 160 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_subaddress, ntv2_subaddress_all); 161 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_read_disable, 0); 162 | ntv2_register_write(ntv2_i2c->kona_reg, ntv2_i2c->kona_control, val); 163 | 164 | res = ntv2_konai2c_wait_for_read(ntv2_i2c, NTV2_READ_TIMEOUT); 165 | if (res < 0) 166 | return res; 167 | 168 | /* disable i2c reads */ 169 | val = NTV2_FLD_SET(ntv2_kona_fld_hdmiin_device_address, ntv2_i2c->i2c_device); 170 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_subaddress, ntv2_subaddress_all); 171 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_read_disable, 1); 172 | ntv2_register_write(ntv2_i2c->kona_reg, ntv2_i2c->kona_control, val); 173 | 174 | res = ntv2_konai2c_wait_for_busy(ntv2_i2c, NTV2_BUSY_TIMEOUT); 175 | if (res < 0) 176 | return res; 177 | 178 | return 0; 179 | } 180 | 181 | u8 ntv2_konai2c_cache_read(struct ntv2_konai2c *ntv2_i2c, u8 address) 182 | { 183 | u32 val; 184 | u32 data; 185 | int res; 186 | 187 | if (ntv2_i2c == NULL) 188 | return 0; 189 | 190 | res = ntv2_konai2c_wait_for_busy(ntv2_i2c, NTV2_BUSY_TIMEOUT); 191 | if (res < 0) { 192 | NTV2_MSG_KONAI2C_ERROR("%s: *error* read dev %02x address %02x failed\n", 193 | ntv2_i2c->name, ntv2_i2c->i2c_device, address); 194 | return res; 195 | } 196 | 197 | val = NTV2_FLD_SET(ntv2_kona_fld_hdmiin_device_address, ntv2_i2c->i2c_device); 198 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_subaddress, address); 199 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_read_disable, 1); 200 | ntv2_register_write(ntv2_i2c->kona_reg, ntv2_i2c->kona_control, val); 201 | 202 | val = ntv2_register_read(ntv2_i2c->kona_reg, ntv2_i2c->kona_data); 203 | data = NTV2_FLD_GET(ntv2_kona_fld_hdmiin_data_in, val); 204 | 205 | NTV2_MSG_KONAI2C_READ("%s: read dev %02x add %02x data %02x\n", 206 | ntv2_i2c->name, ntv2_i2c->i2c_device, address, data); 207 | return (u8)data; 208 | } 209 | 210 | int ntv2_konai2c_rmw(struct ntv2_konai2c *ntv2_i2c, u8 address, u8 data, u8 mask) 211 | { 212 | u8 val; 213 | 214 | val = ntv2_konai2c_cache_read(ntv2_i2c, address); 215 | val = (val & (~mask)) | (data & mask); 216 | return ntv2_konai2c_write(ntv2_i2c, address, val); 217 | } 218 | 219 | static int ntv2_konai2c_wait_for_busy(struct ntv2_konai2c *ntv2_i2c, u32 timeout) 220 | { 221 | u32 val; 222 | u32 mask = NTV2_FLD_MASK(ntv2_kona_fld_hdmiin_i2c_busy); 223 | int count = timeout / NTV2_WAIT_TIME_MIN; 224 | int i; 225 | 226 | if (timeout == 0) { 227 | val = ntv2_register_read(ntv2_i2c->kona_reg, ntv2_i2c->kona_control); 228 | return ((val & mask) == 0)? 0 : -EBUSY; 229 | } 230 | 231 | for (i = 0; i < count; i++) { 232 | val = ntv2_register_read(ntv2_i2c->kona_reg, ntv2_i2c->kona_control); 233 | if ((val & mask) == 0) 234 | return 0; 235 | usleep_range(NTV2_WAIT_TIME_MIN, NTV2_WAIT_TIME_MAX); 236 | } 237 | NTV2_MSG_KONAI2C_ERROR("%s: *error* wait for i2c busy failed - reset count %d\n", 238 | ntv2_i2c->name, ntv2_i2c->reset_count); 239 | ntv2_konai2c_reset(ntv2_i2c); 240 | return -ETIME; 241 | } 242 | 243 | static int ntv2_konai2c_wait_for_write(struct ntv2_konai2c *ntv2_i2c, u32 timeout) 244 | { 245 | u32 val; 246 | u32 mask = NTV2_FLD_MASK(ntv2_kona_fld_hdmiin_write_busy); 247 | int count = timeout / NTV2_WAIT_TIME_MIN; 248 | int i; 249 | 250 | if (timeout == 0) { 251 | val = ntv2_register_read(ntv2_i2c->kona_reg, ntv2_i2c->kona_control); 252 | return ((val & mask) == 0)? 0 : -EBUSY; 253 | } 254 | 255 | for (i = 0; i < count; i++) { 256 | val = ntv2_register_read(ntv2_i2c->kona_reg, ntv2_i2c->kona_control); 257 | if ((val & mask) == 0) 258 | return 0; 259 | usleep_range(NTV2_WAIT_TIME_MIN, NTV2_WAIT_TIME_MAX); 260 | } 261 | NTV2_MSG_KONAI2C_ERROR("%s: *error* wait for i2c write failed - reset count %d\n", 262 | ntv2_i2c->name, ntv2_i2c->reset_count); 263 | ntv2_konai2c_reset(ntv2_i2c); 264 | return -ETIME; 265 | } 266 | 267 | static int ntv2_konai2c_wait_for_read(struct ntv2_konai2c *ntv2_i2c, u32 timeout) 268 | { 269 | u32 val; 270 | u32 mask = NTV2_FLD_MASK(ntv2_kona_fld_hdmiin_ram_data_ready); 271 | int count = timeout / NTV2_WAIT_TIME_MIN; 272 | int i; 273 | 274 | if (timeout == 0) { 275 | val = ntv2_register_read(ntv2_i2c->kona_reg, ntv2_i2c->kona_control); 276 | return ((val & mask) != 0)? 0 : -EBUSY; 277 | } 278 | 279 | for (i = 0; i < count; i++) { 280 | val = ntv2_register_read(ntv2_i2c->kona_reg, ntv2_i2c->kona_control); 281 | if ((val & mask) != 0) 282 | return 0; 283 | usleep_range(NTV2_READ_TIME_MIN, NTV2_READ_TIME_MAX); 284 | } 285 | ntv2_konai2c_reset(ntv2_i2c); 286 | NTV2_MSG_KONAI2C_ERROR("%s: *error* wait for i2c read failed - reset count %d\n", 287 | ntv2_i2c->name, ntv2_i2c->reset_count); 288 | return -ETIME; 289 | } 290 | 291 | static void ntv2_konai2c_reset(struct ntv2_konai2c *ntv2_i2c) 292 | { 293 | u32 val; 294 | 295 | ntv2_i2c->reset_count++; 296 | 297 | /* set reset */ 298 | val = NTV2_FLD_SET(ntv2_kona_fld_hdmiin_device_address, 0); 299 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_subaddress, 0); 300 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_read_disable, 1); 301 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_i2c_reset, 1); 302 | ntv2_register_write(ntv2_i2c->kona_reg, ntv2_i2c->kona_control, val); 303 | 304 | usleep_range(NTV2_RESET_TIME_MIN, NTV2_RESET_TIME_MAX); 305 | 306 | /* clear reset */ 307 | val = NTV2_FLD_SET(ntv2_kona_fld_hdmiin_device_address, 0); 308 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_subaddress, 0); 309 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_read_disable, 1); 310 | val |= NTV2_FLD_SET(ntv2_kona_fld_hdmiin_i2c_reset, 0); 311 | ntv2_register_write(ntv2_i2c->kona_reg, ntv2_i2c->kona_control, val); 312 | 313 | usleep_range(NTV2_RESET_TIME_MIN, NTV2_RESET_TIME_MAX); 314 | } 315 | 316 | 317 | -------------------------------------------------------------------------------- /driver/ntv2_hdmiedid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 HDMI EDID 3 | * 4 | * Copyright 2018 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #include "ntv2_hdmiedid.h" 21 | 22 | 23 | static u8 c_hdmi_port_pefix[] = { 0x03, 0x0c, 0x00 }; 24 | static u8 c_hdmi_port_number[] = { 0x10, 0x20, 0x30, 0x40 }; 25 | 26 | static u8 c_edid_konahdmi_20[] = { 27 | 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x05, 0x41, 0x2E, 0x00, 0x01, 0x01, 0x01, 0x01, 28 | 0x0F, 0x1C, 0x01, 0x03, 0x80, 0xA0, 0x5A, 0x78, 0x0A, 0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 29 | 0x0F, 0x50, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 30 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0xE8, 0x00, 0x30, 0xF2, 0x70, 0x5A, 0x80, 0xB0, 0x58, 31 | 0x8A, 0x00, 0x20, 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 32 | 0x58, 0x2C, 0x45, 0x00, 0x20, 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x17, 33 | 0x3D, 0x0F, 0x88, 0x3C, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xFC, 34 | 0x00, 0x4B, 0x6F, 0x6E, 0x61, 0x20, 0x48, 0x44, 0x4D, 0x49, 0x0A, 0x20, 0x20, 0x20, 0x01, 0xFC, 35 | 36 | 0x02, 0x03, 0x5D, 0x51, 0x57, 0x61, 0x60, 0x5F, 0x5E, 0x5D, 0x66, 0x65, 0x64, 0x63, 0x62, 0x10, 37 | 0x1F, 0x22, 0x21, 0x20, 0x05, 0x14, 0x04, 0x13, 0x06, 0x15, 0x07, 0x16, 0x23, 0x0F, 0x07, 0x07, 38 | 0x83, 0x4F, 0x00, 0x00, 0x70, 0x03, 0x0C, 0x00, 0x10, 0x00, 0x30, 0x3C, 0x20, 0xA0, 0x82, 0x01, 39 | 0x02, 0x03, 0x04, 0x01, 0x41, 0x67, 0xD8, 0x5D, 0xC4, 0x01, 0x78, 0x80, 0x03, 0xE2, 0x00, 0x73, 40 | 0xE3, 0x05, 0xE0, 0x00, 0xE5, 0x0F, 0x63, 0x00, 0x00, 0x00, 0xE3, 0x06, 0x3F, 0x01, 0xEE, 0x01, 41 | 0x46, 0xD0, 0x00, 0x24, 0x0F, 0x8B, 0x00, 0xA8, 0x53, 0x4B, 0x9D, 0x27, 0x0B, 0x01, 0x1D, 0x00, 42 | 0xBE, 0x82, 0x38, 0x2D, 0x40, 0x7E, 0x2C, 0x45, 0x80, 0x20, 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E 44 | }; 45 | 46 | static u8 c_edid_konahdmi_13[] = { 47 | 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x05, 0x41, 0x2E, 0x00, 0x01, 0x01, 0x01, 0x01, 48 | 0x0F, 0x1C, 0x01, 0x03, 0x80, 0xA0, 0x5A, 0x78, 0x0A, 0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 49 | 0x0F, 0x50, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 50 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C, 51 | 0x45, 0x00, 0x20, 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x30, 0x30, 0x30, 52 | 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x17, 53 | 0x3D, 0x0F, 0x44, 0x1E, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xFC, 54 | 0x00, 0x4B, 0x6F, 0x6E, 0x61, 0x20, 0x48, 0x44, 0x4D, 0x49, 0x0A, 0x20, 0x20, 0x20, 0x01, 0x0E, 55 | 56 | 0x02, 0x03, 0x3C, 0x51, 0x4D, 0x10, 0x1F, 0x22, 0x21, 0x20, 0x05, 0x14, 0x04, 0x13, 0x06, 0x15, 57 | 0x07, 0x16, 0x23, 0x0F, 0x07, 0x07, 0x83, 0x4F, 0x00, 0x00, 0x67, 0x03, 0x0C, 0x00, 0x10, 0x00, 58 | 0x30, 0x3C, 0xE2, 0x00, 0x73, 0xE3, 0x05, 0xE0, 0x00, 0xE3, 0x06, 0x3F, 0x01, 0xEE, 0x01, 0x46, 59 | 0xD0, 0x00, 0x24, 0x0F, 0x8B, 0x00, 0xA8, 0x53, 0x4B, 0x9D, 0x27, 0x0B, 0x01, 0x1D, 0x00, 0xBE, 60 | 0x82, 0x38, 0x2D, 0x40, 0x7E, 0x2C, 0x45, 0x80, 0x20, 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x00, 0x00, 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62 64 | }; 65 | 66 | static uint8_t c_edid_corvidhbr[] = { 67 | 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x05, 0x41, 0x18, 0x00, 0x01, 0x01, 0x01, 0x01, 68 | 0x2E, 0x19, 0x01, 0x03, 0x80, 0xA0, 0x5A, 0x78, 0x0A, 0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 69 | 0x0F, 0x50, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 70 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1D, 0x80, 0x3E, 0x73, 0x38, 0x2D, 0x40, 0x7E, 0x2C, 71 | 0x45, 0x80, 0x20, 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 72 | 0x58, 0x2C, 0x45, 0x00, 0x20, 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x17, 73 | 0x3D, 0x0F, 0x88, 0x1E, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xFC, 74 | 0x00, 0x43, 0x6F, 0x72, 0x76, 0x69, 0x64, 0x20, 0x48, 0x42, 0x2D, 0x52, 0x0A, 0x20, 0x01, 0x1A, 75 | 76 | 0x02, 0x03, 0x44, 0x71, 0x55, 0x61, 0x60, 0x5F, 0x5E, 0x5D, 0x66, 0x65, 0x64, 0x63, 0x62, 0x10, 77 | 0x1F, 0x22, 0x21, 0x20, 0x05, 0x14, 0x04, 0x13, 0x06, 0x15, 0x23, 0x0F, 0x04, 0x07, 0x83, 0x4F, 78 | 0x00, 0x00, 0x70, 0x03, 0x0C, 0x00, 0x10, 0x00, 0x10, 0x3C, 0x20, 0xA0, 0x82, 0x01, 0x02, 0x03, 79 | 0x04, 0x01, 0x41, 0xE2, 0x00, 0x73, 0xE3, 0x05, 0xE0, 0x00, 0xE5, 0x0F, 0x63, 0x00, 0x00, 0x00, 80 | 0xE3, 0x06, 0x0F, 0x01, 0x01, 0x1D, 0x00, 0xBE, 0x82, 0x38, 0x2D, 0x40, 0x7E, 0x2C, 0x45, 0x80, 81 | 0x20, 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 82 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 83 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBD 84 | }; 85 | 86 | static u8 c_edid_io4k[] = { 87 | 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x05, 0x41, 0x18, 0x00, 0x01, 0x01, 0x01, 0x01, 88 | 0x2E, 0x19, 0x01, 0x03, 0x80, 0xA0, 0x5A, 0x78, 0x0A, 0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 89 | 0x0F, 0x50, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 90 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1D, 0x80, 0x3E, 0x73, 0x38, 0x2D, 0x40, 0x7E, 0x2C, 91 | 0x45, 0x80, 0x20, 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 92 | 0x58, 0x2C, 0x45, 0x00, 0x20, 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x17, 93 | 0x3D, 0x0F, 0x88, 0x1E, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xFC, 94 | 0x00, 0x49, 0x6F, 0x20, 0x34, 0x4B, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x93, 95 | 96 | 0x02, 0x03, 0x44, 0x71, 0x55, 0x61, 0x60, 0x5F, 0x5E, 0x5D, 0x66, 0x65, 0x64, 0x63, 0x62, 0x10, 97 | 0x1F, 0x22, 0x21, 0x20, 0x05, 0x14, 0x04, 0x13, 0x06, 0x15, 0x23, 0x0F, 0x04, 0x07, 0x83, 0x4F, 98 | 0x00, 0x00, 0x70, 0x03, 0x0C, 0x00, 0x10, 0x00, 0x10, 0x3C, 0x20, 0xA0, 0x82, 0x01, 0x02, 0x03, 99 | 0x04, 0x01, 0x41, 0xE2, 0x00, 0x73, 0xE3, 0x05, 0xE0, 0x00, 0xE5, 0x0F, 0x63, 0x00, 0x00, 0x00, 100 | 0xE3, 0x06, 0x0F, 0x01, 0x01, 0x1D, 0x00, 0xBE, 0x82, 0x38, 0x2D, 0x40, 0x7E, 0x2C, 0x45, 0x80, 101 | 0x20, 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 102 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 103 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBD 104 | }; 105 | 106 | static u8 c_edid_io4kplus[] = { 107 | 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x05, 0x41, 0x2B, 0x00, 0x01, 0x01, 0x01, 0x01, 108 | 0x23, 0x1B, 0x01, 0x03, 0x80, 0xA0, 0x5A, 0x78, 0x0A, 0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 109 | 0x0F, 0x50, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 110 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0xE8, 0x00, 0x30, 0xF2, 0x70, 0x5A, 0x80, 0xB0, 0x58, 111 | 0x8A, 0x00, 0x20, 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 112 | 0x58, 0x2C, 0x45, 0x00, 0x20, 0xC2, 0x31, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x17, 113 | 0x3D, 0x0F, 0x88, 0x3C, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xFC, 114 | 0x00, 0x49, 0x6F, 0x20, 0x34, 0x4B, 0x20, 0x50, 0x6C, 0x75, 0x73, 0x0A, 0x20, 0x20, 0x01, 0xBC, 115 | 116 | 0x02, 0x03, 0x4E, 0x71, 0x57, 0x61, 0x60, 0x5F, 0x5E, 0x5D, 0x66, 0x65, 0x64, 0x63, 0x62, 0x10, 117 | 0x1F, 0x22, 0x21, 0x20, 0x05, 0x14, 0x04, 0x13, 0x02, 0x11, 0x06, 0x15, 0x23, 0x0F, 0x07, 0x07, 118 | 0x83, 0x4F, 0x00, 0x00, 0x70, 0x03, 0x0C, 0x00, 0x10, 0x00, 0x38, 0x3C, 0x20, 0xA0, 0x82, 0x01, 119 | 0x02, 0x03, 0x04, 0x01, 0x41, 0x67, 0xD8, 0x5D, 0xC4, 0x01, 0x78, 0x80, 0x03, 0xE2, 0x00, 0x73, 120 | 0xE3, 0x05, 0xE0, 0x00, 0xE5, 0x0F, 0x63, 0x00, 0x00, 0x00, 0xE3, 0x06, 0x0D, 0x01, 0x01, 0x1D, 121 | 0x00, 0xBE, 0x82, 0x38, 0x2D, 0x40, 0x7E, 0x2C, 0x45, 0x80, 0x20, 0xC2, 0x31, 0x00, 0x00, 0x1E, 122 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 123 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19 124 | }; 125 | 126 | 127 | struct ntv2_hdmiedid *ntv2_hdmiedid_open(struct ntv2_object *ntv2_obj, 128 | const char *name, int index) 129 | { 130 | struct ntv2_hdmiedid *ntv2_hed = NULL; 131 | 132 | ntv2_hed = kzalloc(sizeof(struct ntv2_hdmiedid), GFP_KERNEL); 133 | if (ntv2_hed == NULL) { 134 | NTV2_MSG_ERROR("%s: ntv2_hdmiedid instance memory allocation failed\n", ntv2_obj->name); 135 | return NULL; 136 | } 137 | 138 | ntv2_hed->index = index; 139 | snprintf(ntv2_hed->name, NTV2_STRING_SIZE, "%s-%s%d", ntv2_obj->name, name, index); 140 | INIT_LIST_HEAD(&ntv2_hed->list); 141 | ntv2_hed->ntv2_dev = ntv2_obj->ntv2_dev; 142 | 143 | NTV2_MSG_HDMIIN_INFO("%s: open ntv2_hdmiedid\n", ntv2_hed->name); 144 | 145 | return ntv2_hed; 146 | } 147 | 148 | void ntv2_hdmiedid_close(struct ntv2_hdmiedid *ntv2_hed) 149 | { 150 | if (ntv2_hed == NULL) 151 | return; 152 | 153 | NTV2_MSG_HDMIIN_INFO("%s: close ntv2_hdmiedid\n", ntv2_hed->name); 154 | 155 | memset(ntv2_hed, 0, sizeof(struct ntv2_hdmiedid)); 156 | kfree(ntv2_hed); 157 | } 158 | 159 | int ntv2_hdmiedid_configure(struct ntv2_hdmiedid *ntv2_hed, 160 | enum ntv2_edid_type type, 161 | int port_index) 162 | { 163 | u8 *edid; 164 | u32 size; 165 | u32 start; 166 | u32 end; 167 | u32 count; 168 | u32 prefix_size; 169 | u32 edid_size; 170 | u32 sum; 171 | bool modify_port = false; 172 | u32 i; 173 | u32 j; 174 | 175 | if (ntv2_hed == NULL) 176 | return -EPERM; 177 | 178 | NTV2_MSG_HDMIIN_INFO("%s: configure hdmiedid\n", ntv2_hed->name); 179 | 180 | switch (type) 181 | { 182 | case ntv2_edid_type_konahdmi_20: 183 | edid = c_edid_konahdmi_20; 184 | size = sizeof(c_edid_konahdmi_20); 185 | modify_port = true; 186 | break; 187 | case ntv2_edid_type_konahdmi_13: 188 | edid = c_edid_konahdmi_13; 189 | size = sizeof(c_edid_konahdmi_13); 190 | modify_port = true; 191 | break; 192 | case ntv2_edid_type_corvidhbr: 193 | edid = c_edid_corvidhbr; 194 | size = sizeof(c_edid_corvidhbr); 195 | modify_port = false; 196 | break; 197 | case ntv2_edid_type_io4k: 198 | edid = c_edid_io4k; 199 | size = sizeof(c_edid_io4k); 200 | modify_port = false; 201 | break; 202 | case ntv2_edid_type_io4kplus: 203 | edid = c_edid_io4kplus; 204 | size = sizeof(c_edid_io4kplus); 205 | modify_port = false; 206 | break; 207 | default: 208 | NTV2_MSG_HDMIIN_ERROR("%s: *error* unknown edid type %d\n", ntv2_hed->name, type); 209 | return -EPERM; 210 | } 211 | 212 | if (size > NTV2_HDMI_EDID_SIZE) { 213 | NTV2_MSG_HDMIIN_ERROR("%s: *error* unexpected edid size %d\n", ntv2_hed->name, size); 214 | return -EPERM; 215 | } 216 | 217 | if (port_index >= sizeof(c_hdmi_port_number)) { 218 | NTV2_MSG_HDMIIN_ERROR("%s: *error* unexpected port index %d\n", ntv2_hed->name, port_index); 219 | return -EPERM; 220 | } 221 | 222 | /* copy static edid to buffer */ 223 | memcpy(ntv2_hed->edid_data, edid, size); 224 | ntv2_hed->edid_size = size; 225 | 226 | if (modify_port) { 227 | /* locate and modify edid port number */ 228 | prefix_size = sizeof(c_hdmi_port_pefix); 229 | edid_size = size - prefix_size - 1; 230 | for (i = 0; i < edid_size; i++) { 231 | for (j = 0; j < prefix_size; j++) { 232 | if (c_hdmi_port_pefix[j] != ntv2_hed->edid_data[i + j]) 233 | break; 234 | } 235 | if (j == prefix_size) { 236 | ntv2_hed->edid_data[i + prefix_size] = c_hdmi_port_number[port_index]; 237 | break; 238 | } 239 | } 240 | if (i == edid_size) { 241 | NTV2_MSG_HDMIIN_ERROR("%s: *error* cannot modify port number\n", ntv2_hed->name); 242 | } 243 | } 244 | 245 | /* compute new checksums */ 246 | count = ntv2_hed->edid_size / 128; 247 | for (i = 0; i < count; i++) { 248 | sum = 0; 249 | start = i * 128; 250 | end = start + 127; 251 | for (j = start; j < end; j++) { 252 | sum += ntv2_hed->edid_data[j]; 253 | } 254 | ntv2_hed->edid_data[end] = (u8)((~sum + 1) & 0xff); 255 | } 256 | 257 | return 0; 258 | } 259 | 260 | u8 *ntv2_hdmi_get_edid_data(struct ntv2_hdmiedid *ntv2_hed) 261 | { 262 | if (ntv2_hed == NULL) 263 | return NULL; 264 | 265 | return ntv2_hed->edid_data; 266 | } 267 | 268 | u32 ntv2_hdmi_get_edid_size(struct ntv2_hdmiedid *ntv2_hed) 269 | { 270 | if (ntv2_hed == NULL) 271 | return 0; 272 | 273 | return ntv2_hed->edid_size; 274 | } 275 | 276 | -------------------------------------------------------------------------------- /driver/ntv2_vb2ops.c: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 video buffer ops 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #include "ntv2_video.h" 21 | #include "ntv2_vb2ops.h" 22 | #include "ntv2_v4l2ops.h" 23 | 24 | #ifdef NTV2_USE_VB2_DMA_SG 25 | #include 26 | #else 27 | #include 28 | #endif 29 | 30 | #ifdef NTV2_USE_VB2_V4L2_BUFFER 31 | #define to_ntv2_vb2buf(vb) \ 32 | container_of((to_vb2_v4l2_buffer(vb)), struct ntv2_vb2buf, vb2_v4l2_buffer) 33 | #else 34 | #define to_ntv2_vb2buf(vb) \ 35 | container_of(vb, struct ntv2_vb2buf, vb2_buffer) 36 | #endif 37 | 38 | /* 39 | * Setup the constraints of the queue 40 | */ 41 | #ifdef NTV2_USE_QUEUE_SETUP_DEVICE 42 | static int ntv2_queue_setup(struct vb2_queue *vq, 43 | unsigned int *nbuffers, unsigned int *nplanes, 44 | unsigned int sizes[], struct device *alloc_ctxs[]) 45 | #else 46 | #ifdef NTV2_USE_QUEUE_SETUP_NO_FORMAT 47 | static int ntv2_queue_setup(struct vb2_queue *vq, 48 | unsigned int *nbuffers, unsigned int *nplanes, 49 | unsigned int sizes[], void *alloc_ctxs[]) 50 | #else 51 | #ifdef NTV2_USE_QUEUE_SETUP_PARG 52 | static int ntv2_queue_setup(struct vb2_queue *vq, const void *parg, 53 | unsigned int *nbuffers, unsigned int *nplanes, 54 | unsigned int sizes[], void *alloc_ctxs[]) 55 | #else 56 | static int ntv2_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, 57 | unsigned int *nbuffers, unsigned int *nplanes, 58 | unsigned int sizes[], void *alloc_ctxs[]) 59 | #endif 60 | #endif 61 | #endif 62 | { 63 | struct ntv2_video *ntv2_vid = vb2_get_drv_priv(vq); 64 | #ifndef NTV2_USE_QUEUE_SETUP_NO_FORMAT 65 | #ifdef NTV2_USE_QUEUE_SETUP_PARG 66 | const struct v4l2_format *fmt = parg; 67 | #endif 68 | #endif 69 | unsigned long flags; 70 | 71 | if (ntv2_vid == NULL) 72 | return -EPERM; 73 | 74 | NTV2_MSG_VIDEO_STATE("%s: vb2 queue setup\n", ntv2_vid->name); 75 | 76 | /* require at least 3 buffers */ 77 | if (vq->num_buffers + *nbuffers < 3) 78 | *nbuffers = 3 - vq->num_buffers; 79 | 80 | #ifdef NTV2_USE_QUEUE_SETUP_NO_FORMAT 81 | /* check image size */ 82 | if (*nplanes) 83 | return sizes[0] < ntv2_vid->v4l2_format.sizeimage ? -EINVAL : 0; 84 | 85 | /* configure returned parameters */ 86 | *nplanes = 1; 87 | sizes[0] = ntv2_vid->v4l2_format.sizeimage; 88 | #else 89 | /* check image size */ 90 | if (fmt && fmt->fmt.pix.sizeimage < ntv2_vid->v4l2_format.sizeimage) { 91 | NTV2_MSG_VIDEO_ERROR("%s: *error* vb2 queue setup format image size too small (%d < %d)\n", 92 | ntv2_vid->name, 93 | (int)fmt->fmt.pix.sizeimage, 94 | (int)ntv2_vid->v4l2_format.sizeimage); 95 | return -EINVAL; 96 | } 97 | 98 | /* configure returned parameters */ 99 | *nplanes = 1; 100 | sizes[0] = fmt ? fmt->fmt.pix.sizeimage : ntv2_vid->v4l2_format.sizeimage; 101 | #endif 102 | 103 | /* reset the queue */ 104 | spin_lock_irqsave(&ntv2_vid->vb2_lock, flags); 105 | INIT_LIST_HEAD(&ntv2_vid->vb2buf_list); 106 | ntv2_vid->vb2buf_index = 0; 107 | ntv2_vid->vb2_start = false; 108 | spin_unlock_irqrestore(&ntv2_vid->vb2_lock, flags); 109 | 110 | return 0; 111 | } 112 | 113 | /* 114 | * Initialize the buffer after creation 115 | */ 116 | static int ntv2_vb2buf_init(struct vb2_buffer *vb) 117 | { 118 | struct ntv2_video *ntv2_vid = vb2_get_drv_priv(vb->vb2_queue); 119 | struct ntv2_vb2buf *ntv2_buf = to_ntv2_vb2buf(vb); 120 | unsigned long flags; 121 | 122 | NTV2_MSG_VIDEO_STREAM("%s: vb2 buffer init %d\n", 123 | ntv2_vid->name, ntv2_vid->vb2buf_index); 124 | 125 | spin_lock_irqsave(&ntv2_vid->vb2_lock, flags); 126 | ntv2_buf->index = ntv2_vid->vb2buf_index++; 127 | spin_unlock_irqrestore(&ntv2_vid->vb2_lock, flags); 128 | ntv2_buf->ntv2_vid = ntv2_vid; 129 | ntv2_buf->num_pages = 0; 130 | ntv2_buf->sgtable = NULL; 131 | ntv2_buf->init = true; 132 | 133 | return 0; 134 | } 135 | 136 | /* 137 | * Allocate buffer resources and prepare for queue 138 | */ 139 | static int ntv2_vb2buf_prepare(struct vb2_buffer *vb) 140 | { 141 | struct ntv2_video *ntv2_vid = vb2_get_drv_priv(vb->vb2_queue); 142 | struct ntv2_vb2buf *ntv2_buf = to_ntv2_vb2buf(vb); 143 | struct sg_table *sgtable; 144 | unsigned long size = ntv2_vid->v4l2_format.sizeimage; 145 | int ret; 146 | 147 | NTV2_MSG_VIDEO_STREAM("%s: vb2 buffer prepare %d\n", 148 | ntv2_vid->name, ntv2_buf->index); 149 | 150 | /* check the buffer size */ 151 | if (vb2_plane_size(vb, 0) < size) { 152 | NTV2_MSG_VIDEO_ERROR("%s: *error* vb2 prepare buffer too small (%d < %d)\n", 153 | ntv2_vid->name, (int)vb2_plane_size(vb, 0), (int)size); 154 | return -EINVAL; 155 | } 156 | 157 | vb2_set_plane_payload(vb, 0, size); 158 | 159 | #ifdef NTV2_USE_VB2_DMA_SG 160 | sgtable = vb2_dma_sg_plane_desc(&ntv2_buf->vb2_buffer, 0); 161 | #else 162 | #ifdef NTV2_USE_VB2_V4L2_BUFFER 163 | ret = ntv2_alloc_scatterlist(&ntv2_buf->vmalloc_table, vb2_plane_vaddr(&ntv2_buf->vb2_v4l2_buffer.vb2_buf, 0), size); 164 | #else 165 | ret = ntv2_alloc_scatterlist(&ntv2_buf->vmalloc_table, vb2_plane_vaddr(&ntv2_buf->vb2_buffer, 0), size); 166 | #endif 167 | if (ret < 0) 168 | return -EINVAL; 169 | sgtable = &ntv2_buf->vmalloc_table; 170 | #endif 171 | 172 | /* check scatter data */ 173 | if ((sgtable->sgl == NULL) || 174 | (sgtable->nents == 0)) { 175 | NTV2_MSG_VIDEO_ERROR("%s: *error* vb2 prepare no scatter list\n", ntv2_vid->name); 176 | return -EINVAL; 177 | } 178 | 179 | /* map pages */ 180 | ntv2_buf->num_pages = dma_map_sg(&ntv2_vid->ntv2_dev->pci_dev->dev, 181 | sgtable->sgl, 182 | sgtable->nents, 183 | DMA_FROM_DEVICE); 184 | if (ntv2_buf->num_pages == 0) { 185 | NTV2_MSG_VIDEO_ERROR("%s: *error* map sg failed\n", ntv2_vid->name); 186 | #ifndef NTV2_USE_VB2_DMA_SG 187 | ntv2_free_scatterlist(&ntv2_buf->vmalloc_table); 188 | #endif 189 | return -EINVAL; 190 | } 191 | ntv2_buf->sgtable = sgtable; 192 | 193 | return 0; 194 | } 195 | 196 | /* 197 | * Queue this buffer to be filled 198 | */ 199 | static void ntv2_vb2buf_queue(struct vb2_buffer *vb) 200 | { 201 | struct ntv2_video *ntv2_vid = vb2_get_drv_priv(vb->vb2_queue); 202 | struct ntv2_vb2buf *ntv2_buf = to_ntv2_vb2buf(vb); 203 | unsigned long flags; 204 | 205 | NTV2_MSG_VIDEO_STREAM("%s: vb2 buffer queue %d\n", 206 | ntv2_vid->name, ntv2_buf->index); 207 | 208 | spin_lock_irqsave(&ntv2_vid->vb2_lock, flags); 209 | list_add_tail(&ntv2_buf->list, &ntv2_vid->vb2buf_list); 210 | spin_unlock_irqrestore(&ntv2_vid->vb2_lock, flags); 211 | 212 | /* schedule the dma task */ 213 | tasklet_schedule(&ntv2_vid->transfer_task); 214 | } 215 | 216 | /* 217 | * Free buffer resources 218 | */ 219 | #ifdef NTV2_USE_VB2_VOID_FINISH 220 | static void ntv2_vb2buf_finish(struct vb2_buffer *vb) 221 | #else 222 | static int ntv2_vb2buf_finish(struct vb2_buffer *vb) 223 | #endif 224 | { 225 | struct ntv2_video *ntv2_vid = vb2_get_drv_priv(vb->vb2_queue); 226 | struct ntv2_vb2buf *ntv2_buf = to_ntv2_vb2buf(vb); 227 | struct sg_table *sgtable = ntv2_buf->sgtable; 228 | 229 | NTV2_MSG_VIDEO_STREAM("%s: vb2 buffer finish %d\n", 230 | ntv2_vid->name, ntv2_buf->index); 231 | 232 | /* check scatter data */ 233 | if ((sgtable->sgl == NULL) || 234 | (sgtable->nents == 0) || 235 | (ntv2_buf->num_pages == 0)) { 236 | NTV2_MSG_VIDEO_ERROR("%s: *error* vb2 finish no scatter list\n", ntv2_vid->name); 237 | goto done; 238 | } 239 | 240 | /* unmap the pages */ 241 | dma_unmap_sg(&ntv2_vid->ntv2_dev->pci_dev->dev, 242 | sgtable->sgl, 243 | sgtable->nents, 244 | DMA_FROM_DEVICE); 245 | 246 | ntv2_buf->num_pages = 0; 247 | #ifndef NTV2_USE_VB2_DMA_SG 248 | ntv2_free_scatterlist(&ntv2_buf->vmalloc_table); 249 | #endif 250 | ntv2_buf->sgtable = NULL; 251 | 252 | done: 253 | #ifdef NTV2_USE_VB2_VOID_FINISH 254 | return; 255 | #else 256 | return 0; 257 | #endif 258 | } 259 | 260 | /* 261 | * Release hardware resources 262 | */ 263 | static void ntv2_vb2buf_cleanup(struct vb2_buffer *vb) 264 | { 265 | struct ntv2_video *ntv2_vid = vb2_get_drv_priv(vb->vb2_queue); 266 | struct ntv2_vb2buf *ntv2_buf = to_ntv2_vb2buf(vb); 267 | 268 | NTV2_MSG_VIDEO_STREAM("%s: vb2 buffer cleanup %d\n", 269 | ntv2_vid->name, ntv2_buf->index); 270 | 271 | /* disable video */ 272 | ntv2_video_disable(ntv2_vid); 273 | 274 | ntv2_buf->init = false; 275 | ntv2_buf->index = 0; 276 | } 277 | 278 | /* 279 | * Return all queued buffers 280 | */ 281 | static void ntv2_return_all_buffers(struct ntv2_video *ntv2_vid, 282 | enum vb2_buffer_state state) 283 | { 284 | struct ntv2_vb2buf *buf; 285 | struct ntv2_vb2buf *node; 286 | unsigned long flags; 287 | 288 | NTV2_MSG_VIDEO_STREAM("%s: vb2 return all buffers\n", ntv2_vid->name); 289 | 290 | spin_lock_irqsave(&ntv2_vid->vb2_lock, flags); 291 | list_for_each_entry_safe(buf, node, &ntv2_vid->vb2buf_list, list) { 292 | list_del_init(&buf->list); 293 | #ifdef NTV2_USE_VB2_V4L2_BUFFER 294 | vb2_buffer_done(&buf->vb2_v4l2_buffer.vb2_buf, state); 295 | #else 296 | vb2_buffer_done(&buf->vb2_buffer, state); 297 | #endif 298 | } 299 | spin_unlock_irqrestore(&ntv2_vid->vb2_lock, flags); 300 | } 301 | 302 | /* 303 | * Start streaming 304 | */ 305 | static int ntv2_start_streaming(struct vb2_queue *vq, unsigned int count) 306 | { 307 | struct ntv2_video *ntv2_vid = vb2_get_drv_priv(vq); 308 | unsigned long flags; 309 | int result = 0; 310 | 311 | NTV2_MSG_VIDEO_STATE("%s: vb2 queue start\n", ntv2_vid->name); 312 | 313 | ntv2_vid->vb2buf_sequence = 0; 314 | 315 | /* check for enough buffers queued? */ 316 | 317 | /* enable video */ 318 | result = ntv2_video_enable(ntv2_vid); 319 | if (result != 0) goto error; 320 | 321 | /* start video capture */ 322 | result = ntv2_video_start(ntv2_vid); 323 | if (result != 0) goto error; 324 | 325 | /* synchronize vb2 start */ 326 | spin_lock_irqsave(&ntv2_vid->vb2_lock, flags); 327 | ntv2_vid->vb2_start = true; 328 | spin_unlock_irqrestore(&ntv2_vid->vb2_lock, flags); 329 | 330 | return result; 331 | 332 | error: 333 | /* return all buffer on error */ 334 | ntv2_return_all_buffers(ntv2_vid, VB2_BUF_STATE_QUEUED); 335 | return result; 336 | } 337 | 338 | /* 339 | * Stop streaming 340 | */ 341 | #ifdef NTV2_USE_VB2_VOID_STREAMING 342 | static void ntv2_stop_streaming(struct vb2_queue *vq) 343 | #else 344 | static int ntv2_stop_streaming(struct vb2_queue *vq) 345 | #endif 346 | { 347 | struct ntv2_video *ntv2_vid = vb2_get_drv_priv(vq); 348 | unsigned long flags; 349 | 350 | NTV2_MSG_VIDEO_STATE("%s: vb2 queue stop\n", ntv2_vid->name); 351 | 352 | /* synchronize vb2 stop */ 353 | spin_lock_irqsave(&ntv2_vid->vb2_lock, flags); 354 | ntv2_vid->vb2_start = false; 355 | spin_unlock_irqrestore(&ntv2_vid->vb2_lock, flags); 356 | 357 | /* stop video */ 358 | ntv2_video_stop(ntv2_vid); 359 | ntv2_video_flush(ntv2_vid); 360 | ntv2_video_disable(ntv2_vid); 361 | 362 | /* return all active buffers */ 363 | ntv2_return_all_buffers(ntv2_vid, VB2_BUF_STATE_ERROR); 364 | 365 | #ifdef NTV2_USE_VB2_VOID_STREAMING 366 | return; 367 | #else 368 | return 0; 369 | #endif 370 | } 371 | 372 | 373 | static struct vb2_ops ntv2_vb2ops = { 374 | .queue_setup = ntv2_queue_setup, 375 | .buf_init = ntv2_vb2buf_init, 376 | .buf_prepare = ntv2_vb2buf_prepare, 377 | .buf_queue = ntv2_vb2buf_queue, 378 | .buf_finish = ntv2_vb2buf_finish, 379 | .buf_cleanup = ntv2_vb2buf_cleanup, 380 | .start_streaming = ntv2_start_streaming, 381 | .stop_streaming = ntv2_stop_streaming, 382 | .wait_prepare = vb2_ops_wait_prepare, 383 | .wait_finish = vb2_ops_wait_finish, 384 | }; 385 | 386 | int ntv2_vb2ops_configure(struct ntv2_video *ntv2_vid) 387 | { 388 | struct vb2_queue *que; 389 | int result; 390 | 391 | /* configure the vb2 queue */ 392 | que = &ntv2_vid->vb2_queue; 393 | que->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 394 | que->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; 395 | que->drv_priv = ntv2_vid; 396 | que->buf_struct_size = sizeof(struct ntv2_vb2buf); 397 | que->ops = &ntv2_vb2ops; 398 | #ifdef NTV2_USE_VB2_DMA_SG 399 | que->mem_ops = &vb2_dma_sg_memops; 400 | #else 401 | que->mem_ops = &vb2_vmalloc_memops; 402 | #endif 403 | #ifdef NTV2_USE_VB2_TIMESTAMP_FLAGS 404 | que->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 405 | que->min_buffers_needed = 2; 406 | #else 407 | que->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 408 | #endif 409 | que->lock = &ntv2_vid->vb2_mutex; 410 | que->gfp_flags = 0; 411 | 412 | result = vb2_queue_init(que); 413 | if (result != 0) { 414 | NTV2_MSG_VIDEO_ERROR("%s: *error* vb2_queue_init failed code %d\n", 415 | ntv2_vid->name, result); 416 | return result; 417 | } 418 | ntv2_vid->vb2_init = true; 419 | 420 | return 0; 421 | } 422 | 423 | struct ntv2_vb2buf *ntv2_vb2ops_vb2buf_ready(struct ntv2_video *ntv2_vid) 424 | { 425 | struct ntv2_vb2buf *buf = NULL; 426 | unsigned long flags; 427 | 428 | if (ntv2_vid == NULL) 429 | return NULL; 430 | 431 | /* get the next buffer */ 432 | spin_lock_irqsave(&ntv2_vid->vb2_lock, flags); 433 | if (ntv2_vid->vb2_start && !list_empty(&ntv2_vid->vb2buf_list)) { 434 | buf = list_first_entry(&ntv2_vid->vb2buf_list, struct ntv2_vb2buf, list); 435 | } 436 | spin_unlock_irqrestore(&ntv2_vid->vb2_lock, flags); 437 | 438 | if (buf != NULL) 439 | NTV2_MSG_VIDEO_STREAM("%s: vb2 buffer ready %d\n", 440 | ntv2_vid->name, buf->index); 441 | 442 | return buf; 443 | } 444 | 445 | void ntv2_vb2ops_vb2buf_done(struct ntv2_vb2buf *ntv2_buf) 446 | { 447 | struct ntv2_video *ntv2_vid; 448 | struct v4l2_timecode *timecode; 449 | unsigned long flags; 450 | 451 | if (ntv2_buf == NULL) 452 | return; 453 | 454 | ntv2_vid = ntv2_buf->ntv2_vid; 455 | if (ntv2_vid == NULL) 456 | return; 457 | 458 | NTV2_MSG_VIDEO_STREAM("%s: vb2 buffer done %d\n", 459 | ntv2_vid->name, ntv2_buf->index); 460 | 461 | #ifdef NTV2_USE_VB2_V4L2_BUFFER 462 | if ((ntv2_buf->vb2_v4l2_buffer.flags & V4L2_BUF_FLAG_TIMECODE) != 0) { 463 | timecode = &ntv2_buf->vb2_v4l2_buffer.timecode; 464 | #else 465 | if ((ntv2_buf->vb2_buffer.v4l2_buf.flags & V4L2_BUF_FLAG_TIMECODE) != 0) { 466 | timecode = &ntv2_buf->vb2_buffer.v4l2_buf.timecode; 467 | #endif 468 | NTV2_MSG_VIDEO_STREAM("%s: vb2 timecode type %d drop %s time %02d:%02d:%02d:%02d user %02x %02x %02x %02x\n", 469 | ntv2_vid->name, 470 | timecode->type, 471 | (((timecode->flags & V4L2_TC_FLAG_DROPFRAME) != 0)? "y" : "n"), 472 | timecode->hours, 473 | timecode->minutes, 474 | timecode->seconds, 475 | timecode->frames, 476 | timecode->userbits[0], 477 | timecode->userbits[1], 478 | timecode->userbits[2], 479 | timecode->userbits[3]); 480 | } 481 | 482 | /* remove from list */ 483 | spin_lock_irqsave(&ntv2_vid->vb2_lock, flags); 484 | if (ntv2_vid->vb2_start) { 485 | list_del_init(&ntv2_buf->list); 486 | 487 | /* mark as done */ 488 | #ifdef NTV2_USE_VB2_V4L2_BUFFER 489 | vb2_set_plane_payload(&ntv2_buf->vb2_v4l2_buffer.vb2_buf, 0, ntv2_vid->v4l2_format.sizeimage); 490 | vb2_buffer_done(&ntv2_buf->vb2_v4l2_buffer.vb2_buf, VB2_BUF_STATE_DONE); 491 | #else 492 | vb2_set_plane_payload(&ntv2_buf->vb2_buffer, 0, ntv2_vid->v4l2_format.sizeimage); 493 | vb2_buffer_done(&ntv2_buf->vb2_buffer, VB2_BUF_STATE_DONE); 494 | #endif 495 | } 496 | spin_unlock_irqrestore(&ntv2_vid->vb2_lock, flags); 497 | } 498 | -------------------------------------------------------------------------------- /driver/ntv2_params.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 device parameters 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #ifndef NTV2_PARAMS_H 21 | #define NTV2_PARAMS_H 22 | 23 | #define NTV2_MODULE_NAME KBUILD_MODNAME 24 | #define NTV2_DRV_VERSION "1.2.2" 25 | 26 | #define NTV2_PCI_VENID 0xf1d0 27 | #define NTV2_PCI_DEVID_KONA4 0xeb0b 28 | #define NTV2_PCI_DEVID_CORVID88 0xeb0d 29 | #define NTV2_PCI_DEVID_CORVID44 0xeb0e 30 | #define NTV2_PCI_DEVID_CORVIDHBR 0xeb18 31 | #define NTV2_PCI_DEVID_KONAHDMI 0xeb24 32 | #define NTV2_PCI_DEVID_KONA1 0xeb23 33 | 34 | #define NTV2_DEVICE_ID_KONA4 0x10518400 35 | #define NTV2_DEVICE_ID_CORVID88 0x10538200 36 | #define NTV2_DEVICE_ID_CORVID44 0x10565400 37 | #define NTV2_DEVICE_ID_CORVIDHBR 0x10668200 38 | #define NTV2_DEVICE_ID_KONAHDMI 0x10767400 39 | #define NTV2_DEVICE_ID_KONA1 0x10756600 40 | 41 | #define NTV2_PCI_BAR_NWL 0 42 | #define NTV2_PCI_BAR_VIDEO 1 43 | 44 | #define NTV2_STRING_SIZE 80 45 | 46 | #define NTV2_MAX_CHANNELS 8 47 | #define NTV2_MAX_STREAMS 4 48 | #define NTV2_MAX_SDI_INPUTS 8 49 | #define NTV2_MAX_HDMI_INPUTS 4 50 | #define NTV2_MAX_VIDEO_FORMATS 32 51 | #define NTV2_MAX_PIXEL_FORMATS 8 52 | #define NTV2_MAX_INPUT_CONFIGS 8 53 | #define NTV2_MAX_CSC_CONFIGS 4 54 | #define NTV2_MAX_SOURCE_CONFIGS 8 55 | #define NTV2_MAX_FRAME_RATES 16 56 | #define NTV2_MAX_VIDEO_STANDARDS 16 57 | #define NTV2_MAX_FRAME_GEOMETRIES 24 58 | #define NTV2_MAX_INPUT_GEOMETRIES 8 59 | #define NTV2_MAX_COLOR_SPACES 8 60 | #define NTV2_MAX_COLOR_DEPTHS 8 61 | #define NTV2_MAX_DMA_ENGINES 4 62 | 63 | #define NTV2_MAX_UARTS 16 64 | #define NTV2_TTY_NAME "ttyNTV" 65 | 66 | #define NTV2_MAX_CDEVS 16 67 | #define NTV2_CDEV_NAME "ntv2dev" 68 | 69 | #ifdef NTV2_REG_CONST 70 | #define NTV2_REG_ARGS(a1, a2, a3, a4, a5, a6, a7, a8, aN, ...) aN 71 | #define NTV2_REG(reg, ...) \ 72 | const u32 reg[] = { NTV2_REG_ARGS(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1), __VA_ARGS__ } 73 | #define NTV2_FLD(field, size, shift) const u32 field = (((size) << 16) | (shift)) 74 | #else 75 | #define NTV2_REG(reg, ...) extern const u32 reg[] 76 | #define NTV2_FLD(field, size, shift) extern const u32 field 77 | #endif 78 | 79 | #define NTV2_CON(con, value) enum { con = (value) } 80 | 81 | #define NTV2_REG_COUNT(reg) (reg[0]) 82 | #define NTV2_REG_NUM(reg, index) (((index) < NTV2_REG_COUNT(reg))? reg[(index) + 1] : 0) 83 | 84 | #define NTV2_FLD_SIZE(field) ((field) >> 16) 85 | #define NTV2_FLD_SHIFT(field) ((field) & 0xffff) 86 | #define NTV2_FLD_MASK(field) ((((u32)0x1 << NTV2_FLD_SIZE(field)) - 1) << NTV2_FLD_SHIFT(field)) 87 | #define NTV2_FLD_GET(field, value) ((((u32)value) & NTV2_FLD_MASK(field)) >> NTV2_FLD_SHIFT(field)) 88 | #define NTV2_FLD_SET(field, value) ((((u32)value) << NTV2_FLD_SHIFT(field)) & NTV2_FLD_MASK(field)) 89 | 90 | #define NTV2_U64_HIGH(value) ((u32)((value) >> 32)) 91 | #define NTV2_U64_LOW(value) ((u32)(value)) 92 | #define NTV2_U64_BUILD(high, low) ((((u64)(high)) << 32) | ((u64)(low))) 93 | 94 | #define NTV2_FOURCC_CHARS(fourcc) \ 95 | *((char*)fourcc), *(((char*)fourcc)+1), *(((char*)fourcc)+2), *(((char*)fourcc)+3) 96 | 97 | #define NTV2_DEBUG_REGISTER 32 98 | 99 | /* debug print macros */ 100 | #define NTV2_DEBUG_INFO 0x00000001 101 | #define NTV2_DEBUG_ERROR 0x00000002 102 | #define NTV2_DEBUG_PCI_STATE 0x00000010 103 | #define NTV2_DEBUG_CHANNEL_STATISTICS 0x00000020 104 | #define NTV2_DEBUG_INPUT_STATE 0x00000100 105 | #define NTV2_DEBUG_VIDEO_STATE 0x00000200 106 | #define NTV2_DEBUG_AUDIO_STATE 0x00000400 107 | #define NTV2_DEBUG_CHANNEL_STATE 0x00000800 108 | #define NTV2_DEBUG_HDMIIN_STATE 0x00001000 109 | #define NTV2_DEBUG_HDMIIN_DETECT 0x00002000 110 | #define NTV2_DEBUG_SERIAL_STATE 0x00004000 111 | #define NTV2_DEBUG_CHRDEV_STATE 0x00008000 112 | #define NTV2_DEBUG_VIDEO_STREAM 0x00100000 113 | #define NTV2_DEBUG_AUDIO_STREAM 0x00200000 114 | #define NTV2_DEBUG_CHANNEL_STREAM 0x00400000 115 | #define NTV2_DEBUG_SERIAL_STREAM 0x00800000 116 | #define NTV2_DEBUG_REGISTER_READ 0x01000000 117 | #define NTV2_DEBUG_REGISTER_WRITE 0x02000000 118 | #define NTV2_DEBUG_KONAI2C_READ 0x04000000 119 | #define NTV2_DEBUG_KONAI2C_WRITE 0x08000000 120 | #define NTV2_DEBUG_DMA_STATE 0x10000000 121 | #define NTV2_DEBUG_DMA_STREAM 0x20000000 122 | #define NTV2_DEBUG_DMA_DESCRIPTOR 0x40000000 123 | #define NTV2_DEBUG_DMA_STATISTICS 0x80000000 124 | 125 | #define NTV2_DEBUG_ACTIVE(msg_mask) \ 126 | ((ntv2_module_info()->debug_mask & msg_mask) != 0) 127 | 128 | #define NTV2_MSG_PRINT(msg_mask, string, ...) \ 129 | if(NTV2_DEBUG_ACTIVE(msg_mask)) printk(string, __VA_ARGS__); 130 | 131 | #define NTV2_MSG_INFO(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_INFO, string, __VA_ARGS__) 132 | #define NTV2_MSG_ERROR(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_ERROR, string, __VA_ARGS__) 133 | #define NTV2_MSG_PCI_INFO(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_INFO, string, __VA_ARGS__) 134 | #define NTV2_MSG_PCI_ERROR(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_ERROR, string, __VA_ARGS__) 135 | #define NTV2_MSG_PCI_STATE(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_PCI_STATE, string, __VA_ARGS__) 136 | #define NTV2_MSG_DEVICE_INFO(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_INFO, string, __VA_ARGS__) 137 | #define NTV2_MSG_DEVICE_ERROR(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_ERROR, string, __VA_ARGS__) 138 | #define NTV2_MSG_REGISTER_INFO(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_INFO, string, __VA_ARGS__) 139 | #define NTV2_MSG_REGISTER_ERROR(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_ERROR, string, __VA_ARGS__) 140 | #define NTV2_MSG_REGISTER_READ(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_REGISTER_READ, string, __VA_ARGS__) 141 | #define NTV2_MSG_REGISTER_WRITE(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_REGISTER_WRITE, string, __VA_ARGS__) 142 | #define NTV2_MSG_DMA_INFO(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_INFO, string, __VA_ARGS__) 143 | #define NTV2_MSG_DMA_ERROR(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_ERROR, string, __VA_ARGS__) 144 | #define NTV2_MSG_DMA_STATE(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_DMA_STATE, string, __VA_ARGS__) 145 | #define NTV2_MSG_DMA_STREAM(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_DMA_STREAM, string, __VA_ARGS__) 146 | #define NTV2_MSG_DMA_DESCRIPTOR(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_DMA_DESCRIPTOR, string, __VA_ARGS__) 147 | #define NTV2_MSG_DMA_STATISTICS(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_DMA_STATISTICS, string, __VA_ARGS__) 148 | #define NTV2_MSG_INPUT_INFO(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_INFO, string, __VA_ARGS__) 149 | #define NTV2_MSG_INPUT_ERROR(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_ERROR, string, __VA_ARGS__) 150 | #define NTV2_MSG_INPUT_STATE(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_INPUT_STATE, string, __VA_ARGS__) 151 | #define NTV2_MSG_VIDEO_INFO(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_INFO, string, __VA_ARGS__) 152 | #define NTV2_MSG_VIDEO_ERROR(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_ERROR, string, __VA_ARGS__) 153 | #define NTV2_MSG_VIDEO_STATE(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_VIDEO_STATE, string, __VA_ARGS__) 154 | #define NTV2_MSG_VIDEO_STREAM(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_VIDEO_STREAM, string, __VA_ARGS__) 155 | #define NTV2_MSG_AUDIO_INFO(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_INFO, string, __VA_ARGS__) 156 | #define NTV2_MSG_AUDIO_ERROR(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_ERROR, string, __VA_ARGS__) 157 | #define NTV2_MSG_AUDIO_STATE(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_AUDIO_STATE, string, __VA_ARGS__) 158 | #define NTV2_MSG_AUDIO_STREAM(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_AUDIO_STREAM, string, __VA_ARGS__) 159 | #define NTV2_MSG_CHANNEL_INFO(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_INFO, string, __VA_ARGS__) 160 | #define NTV2_MSG_CHANNEL_ERROR(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_ERROR, string, __VA_ARGS__) 161 | #define NTV2_MSG_CHANNEL_STATE(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_CHANNEL_STATE, string, __VA_ARGS__) 162 | #define NTV2_MSG_CHANNEL_STREAM(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_CHANNEL_STREAM, string, __VA_ARGS__) 163 | #define NTV2_MSG_CHANNEL_STATISTICS(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_CHANNEL_STATISTICS, string, __VA_ARGS__) 164 | #define NTV2_MSG_KONAI2C_INFO(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_INFO, string, __VA_ARGS__) 165 | #define NTV2_MSG_KONAI2C_ERROR(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_ERROR, string, __VA_ARGS__) 166 | #define NTV2_MSG_KONAI2C_READ(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_KONAI2C_READ, string, __VA_ARGS__) 167 | #define NTV2_MSG_KONAI2C_WRITE(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_KONAI2C_WRITE, string, __VA_ARGS__) 168 | #define NTV2_MSG_HDMIIN_INFO(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_INFO, string, __VA_ARGS__) 169 | #define NTV2_MSG_HDMIIN_ERROR(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_ERROR, string, __VA_ARGS__) 170 | #define NTV2_MSG_HDMIIN_STATE(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_HDMIIN_STATE, string, __VA_ARGS__) 171 | #define NTV2_MSG_HDMIIN_DETECT(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_HDMIIN_DETECT, string, __VA_ARGS__) 172 | #define NTV2_MSG_SERIAL_INFO(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_INFO, string, __VA_ARGS__) 173 | #define NTV2_MSG_SERIAL_ERROR(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_ERROR, string, __VA_ARGS__) 174 | #define NTV2_MSG_SERIAL_STATE(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_SERIAL_STATE, string, __VA_ARGS__) 175 | #define NTV2_MSG_SERIAL_STREAM(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_SERIAL_STREAM, string, __VA_ARGS__) 176 | #define NTV2_MSG_CHRDEV_INFO(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_INFO, string, __VA_ARGS__) 177 | #define NTV2_MSG_CHRDEV_ERROR(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_ERROR, string, __VA_ARGS__) 178 | #define NTV2_MSG_CHRDEV_STATE(string, ...) NTV2_MSG_PRINT(NTV2_DEBUG_CHRDEV_STATE, string, __VA_ARGS__) 179 | 180 | struct ntv2_register; 181 | struct ntv2_pci; 182 | struct ntv2_channel; 183 | struct ntv2_video; 184 | struct ntv2_audio; 185 | struct ntv2_input; 186 | struct ntv2_chrdev; 187 | 188 | enum ntv2_pci_type { 189 | ntv2_pci_type_unknown, 190 | ntv2_pci_type_nwl, 191 | ntv2_pci_type_xlx, 192 | ntv2_pci_type_size 193 | }; 194 | 195 | enum ntv2_stream_type { 196 | ntv2_stream_type_unknown, 197 | ntv2_stream_type_vidin, 198 | ntv2_stream_type_vidout, 199 | ntv2_stream_type_audin, 200 | ntv2_stream_type_audout, 201 | ntv2_stream_type_size 202 | }; 203 | 204 | enum ntv2_input_type { 205 | ntv2_input_type_unknown, 206 | ntv2_input_type_auto, 207 | ntv2_input_type_sdi, 208 | ntv2_input_type_hdmi_adv, 209 | ntv2_input_type_hdmi_aja, 210 | ntv2_input_type_aes, 211 | ntv2_input_type_analog, 212 | ntv2_input_type_size 213 | }; 214 | 215 | enum ntv2_task_state { 216 | ntv2_task_state_unknown, 217 | ntv2_task_state_enable, 218 | ntv2_task_state_disable, 219 | ntv2_task_state_size 220 | }; 221 | 222 | enum ntv2_transfer_mode { 223 | ntv2_transfer_mode_unknown, 224 | ntv2_transfer_mode_s2c, 225 | ntv2_transfer_mode_c2s, 226 | ntv2_transfer_mode_size 227 | }; 228 | 229 | enum ntv2_edid_type { 230 | ntv2_edid_type_unknown, 231 | ntv2_edid_type_konahdmi_20, 232 | ntv2_edid_type_konahdmi_13, 233 | ntv2_edid_type_corvidhbr, 234 | ntv2_edid_type_io4k, 235 | ntv2_edid_type_io4kplus, 236 | ntv2_edid_type_size 237 | }; 238 | 239 | #ifdef NTV2_USE_VB2_BUFFER_TIMESTAMP 240 | typedef u64 v4l2_time_t; 241 | #else 242 | typedef struct timeval v4l2_time_t; 243 | #endif 244 | 245 | struct ntv2_object { 246 | int index; 247 | char name[NTV2_STRING_SIZE]; 248 | struct list_head list; 249 | struct ntv2_device *ntv2_dev; 250 | }; 251 | 252 | struct ntv2_video_format { 253 | const char *name; 254 | struct v4l2_dv_timings v4l2_timings; 255 | u32 video_standard; 256 | u32 frame_geometry; 257 | u32 frame_rate; 258 | u32 frame_flags; 259 | }; 260 | 261 | struct ntv2_pixel_format { 262 | const char *name; 263 | u32 v4l2_pixel_format; 264 | u32 ntv2_pixel_format; 265 | u32 pixel_flags; 266 | u32 cadence_pixels; 267 | u32 cadence_bytes; 268 | u32 pitch_alignment; 269 | }; 270 | 271 | struct ntv2_input_format { 272 | enum ntv2_input_type type; 273 | u32 video_standard; 274 | u32 frame_rate; 275 | u32 frame_flags; 276 | u32 pixel_flags; 277 | int reg_index; 278 | int input_index; 279 | int num_inputs; 280 | int num_streams; 281 | }; 282 | 283 | struct ntv2_source_format { 284 | enum ntv2_input_type type; 285 | u32 audio_source; 286 | u32 audio_detect; 287 | int reg_index; 288 | int input_index; 289 | int num_inputs; 290 | }; 291 | 292 | struct ntv2_sdi_input_status { 293 | int input_index; 294 | u32 input_geometry; 295 | u32 frame_rate; 296 | bool progressive; 297 | u32 interface; 298 | u32 vpid_ds1; 299 | u32 vpid_ds2; 300 | u32 audio_detect; 301 | }; 302 | 303 | struct ntv2_aes_input_status { 304 | int input_index; 305 | u32 audio_detect; 306 | }; 307 | 308 | struct ntv2_interrupt_status { 309 | u32 interrupt_status[2]; 310 | v4l2_time_t v4l2_time; 311 | }; 312 | 313 | typedef void (*ntv2_transfer_callback)(unsigned long, int); 314 | 315 | struct ntv2_transfer { 316 | enum ntv2_transfer_mode mode; 317 | struct scatterlist *sg_list; 318 | u32 sg_pages; 319 | u32 sg_offset; 320 | u32 card_address[2]; 321 | u32 card_size[2]; 322 | ntv2_transfer_callback callback_func; 323 | unsigned long callback_data; 324 | }; 325 | 326 | struct ntv2_device { 327 | int index; 328 | char name[NTV2_STRING_SIZE]; 329 | struct list_head list; 330 | struct ntv2_device *ntv2_dev; 331 | 332 | struct ntv2_module *ntv2_mod; 333 | bool init; 334 | 335 | struct pci_dev *pci_dev; 336 | enum ntv2_pci_type pci_type; 337 | bool pci_region; 338 | bool vid_region; 339 | int pci_bar; 340 | int vid_bar; 341 | void __iomem *pci_base; 342 | void __iomem *vid_base; 343 | u32 pci_size; 344 | u32 vid_size; 345 | 346 | bool irq_msi; 347 | irq_handler_t irq_handler; 348 | struct ntv2_register *pci_reg; 349 | struct ntv2_register *vid_reg; 350 | struct ntv2_pci *pci_dma; 351 | struct ntv2_features *features; 352 | struct ntv2_input *inp_mon; 353 | struct ntv2_chrdev *chr_dev; 354 | struct snd_card *snd_card; 355 | 356 | struct list_head video_list; 357 | spinlock_t video_lock; 358 | atomic_t video_index; 359 | 360 | struct list_head audio_list; 361 | spinlock_t audio_lock; 362 | atomic_t audio_index; 363 | 364 | struct list_head channel_list; 365 | spinlock_t channel_lock; 366 | atomic_t channel_index; 367 | 368 | struct list_head serial_list; 369 | spinlock_t serial_lock; 370 | atomic_t serial_index; 371 | }; 372 | 373 | struct ntv2_module { 374 | const char *name; 375 | u32 debug_mask; 376 | const char *version; 377 | bool init; 378 | 379 | struct list_head device_list; 380 | spinlock_t device_lock; 381 | atomic_t device_index; 382 | 383 | struct uart_driver *uart_driver; 384 | u32 uart_max; 385 | atomic_t uart_index; 386 | 387 | dev_t cdev_number; 388 | u32 cdev_max; 389 | const char *cdev_name; 390 | atomic_t cdev_index; 391 | }; 392 | 393 | void ntv2_module_initialize(void); 394 | void ntv2_module_release(void); 395 | 396 | struct ntv2_module *ntv2_module_info(void); 397 | 398 | s64 ntv2_system_time(void); 399 | 400 | int ntv2_wait(int *event, int state, int timeout); 401 | 402 | const char* ntv2_stream_name(enum ntv2_stream_type type); 403 | const char* ntv2_pci_name(enum ntv2_pci_type type); 404 | 405 | int ntv2_alloc_scatterlist(struct sg_table *sgt, u8* vm_buffer, u32 vm_size); 406 | void ntv2_free_scatterlist(struct sg_table *sgt); 407 | 408 | #endif 409 | -------------------------------------------------------------------------------- /driver/ntv2_audioops.c: -------------------------------------------------------------------------------- 1 | /* 2 | * NTV2 audio stream channel ops 3 | * 4 | * Copyright 2016 AJA Video Systems Inc. All rights reserved. 5 | * 6 | * This program is free software; you may redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 | * SOFTWARE. 18 | */ 19 | 20 | #include "ntv2_audioops.h" 21 | #include "ntv2_channel.h" 22 | #include "ntv2_konareg.h" 23 | #include "ntv2_register.h" 24 | 25 | 26 | #include "ntv2_features.h" 27 | 28 | int ntv2_audioops_setup_capture(struct ntv2_channel_stream *stream) 29 | { 30 | struct ntv2_channel *ntv2_chn = stream->ntv2_chn; 31 | struct ntv2_features *features = ntv2_chn->features; 32 | struct ntv2_audio_config *audio_config; 33 | int index = ntv2_chn->index; 34 | u32 val; 35 | u32 mask; 36 | int i; 37 | 38 | audio_config = ntv2_features_get_audio_config(features, ntv2_chn->index); 39 | 40 | /* initialize audio input stream data */ 41 | INIT_LIST_HEAD(&stream->data_ready_list); 42 | INIT_LIST_HEAD(&stream->data_done_list); 43 | stream->queue_run = false; 44 | stream->queue_last = false; 45 | stream->audio.sample_rate = audio_config->sample_rate; 46 | stream->audio.num_channels = audio_config->num_channels; 47 | stream->audio.sample_size = audio_config->sample_size; 48 | stream->audio.audio_offset = 0; 49 | stream->audio.ring_address = ntv2_features_get_audio_capture_address(features, ntv2_chn->index); 50 | stream->audio.ring_offset = audio_config->ring_size; 51 | stream->audio.ring_size = audio_config->ring_size; 52 | stream->audio.ring_init = 53 | audio_config->ring_offset_samples * 54 | audio_config->num_channels * 55 | audio_config->sample_size; 56 | stream->audio.sync_cadence = 0; 57 | stream->audio.sync_tolerance = audio_config->sync_tolerance; 58 | stream->audio.total_sample_count = 0; 59 | stream->audio.total_drop_count = 0; 60 | stream->audio.stat_sample_count = 0; 61 | stream->audio.stat_drop_count = 0; 62 | stream->audio.hardware_enable = false; 63 | 64 | /* initialize audio data buffers */ 65 | for (i = 0; i < NTV2_MAX_CHANNEL_BUFFERS; i++) { 66 | stream->data_array[i].index = i; 67 | stream->data_array[i].type = stream->type; 68 | INIT_LIST_HEAD(&stream->data_array[i].list); 69 | stream->data_array[i].ntv2_str = stream; 70 | list_add_tail(&stream->data_array[i].list, &stream->data_done_list); 71 | } 72 | 73 | /* setup audio input (disable capture) */ 74 | val = NTV2_FLD_SET(ntv2_kona_fld_audio_capture_enable, 0); 75 | mask = NTV2_FLD_MASK(ntv2_kona_fld_audio_capture_enable); 76 | val |= NTV2_FLD_SET(ntv2_kona_fld_audio_input_reset, 1); 77 | mask |= NTV2_FLD_MASK(ntv2_kona_fld_audio_input_reset); 78 | val |= NTV2_FLD_SET(ntv2_kona_fld_audio_16_channel, 1); 79 | mask |= NTV2_FLD_MASK(ntv2_kona_fld_audio_16_channel); 80 | val |= NTV2_FLD_SET(ntv2_kona_fld_audio_big_buffer, 0); 81 | mask |= NTV2_FLD_MASK(ntv2_kona_fld_audio_big_buffer); 82 | ntv2_reg_rmw(ntv2_chn->vid_reg, ntv2_kona_reg_audio_control, index, val, mask); 83 | 84 | /* setup audio source */ 85 | val = NTV2_FLD_SET(ntv2_kona_fld_audio_input_ch12, ntv2_kona_audio_source_embedded); 86 | val |= NTV2_FLD_SET(ntv2_kona_fld_audio_input_ch34, ntv2_kona_audio_source_embedded); 87 | val |= NTV2_FLD_SET(ntv2_kona_fld_audio_input_ch56, ntv2_kona_audio_source_embedded); 88 | val |= NTV2_FLD_SET(ntv2_kona_fld_audio_input_ch78, ntv2_kona_audio_source_embedded); 89 | ntv2_reg_write(ntv2_chn->vid_reg, ntv2_kona_reg_audio_source, index, val); 90 | 91 | stream->audio.embedded_clock = false; 92 | 93 | return 0; 94 | } 95 | 96 | int ntv2_audioops_update_mode(struct ntv2_channel_stream *stream) 97 | { 98 | struct ntv2_channel *ntv2_chn = stream->ntv2_chn; 99 | int index = ntv2_chn->index; 100 | u32 val; 101 | u32 mask; 102 | 103 | /* enable audio capture */ 104 | if (stream->queue_enable) { 105 | val = NTV2_FLD_SET(ntv2_kona_fld_audio_capture_enable, 1); 106 | mask = NTV2_FLD_MASK(ntv2_kona_fld_audio_capture_enable); 107 | val |= NTV2_FLD_SET(ntv2_kona_fld_audio_input_reset, 0); 108 | mask |= NTV2_FLD_MASK(ntv2_kona_fld_audio_input_reset); 109 | ntv2_reg_rmw(ntv2_chn->vid_reg, ntv2_kona_reg_audio_control, index, val, mask); 110 | stream->audio.hardware_enable = true; 111 | } else { 112 | val = NTV2_FLD_SET(ntv2_kona_fld_audio_capture_enable, 0); 113 | mask = NTV2_FLD_MASK(ntv2_kona_fld_audio_capture_enable); 114 | val |= NTV2_FLD_SET(ntv2_kona_fld_audio_input_reset, 1); 115 | mask |= NTV2_FLD_MASK(ntv2_kona_fld_audio_input_reset); 116 | ntv2_reg_rmw(ntv2_chn->vid_reg, ntv2_kona_reg_audio_control, index, val, mask); 117 | stream->audio.hardware_enable = false; 118 | } 119 | 120 | return 0; 121 | } 122 | 123 | int ntv2_audioops_update_route(struct ntv2_channel_stream *stream) 124 | { 125 | struct ntv2_channel *ntv2_chn = stream->ntv2_chn; 126 | struct ntv2_channel_stream *video_stream = NULL; 127 | struct ntv2_source_config *source_config = NULL; 128 | struct ntv2_source_format source_format; 129 | struct ntv2_features *features = ntv2_chn->features; 130 | int index = ntv2_chn->index; 131 | u32 org_source = ntv2_kona_audio_source_aes; 132 | u32 org_bit0 = 0; 133 | u32 org_bit1 = 0; 134 | u32 new_source = ntv2_kona_audio_source_aes; 135 | u32 new_bit0 = 0; 136 | u32 new_bit1 = 0; 137 | u32 val; 138 | u32 mask; 139 | 140 | /* get original audio source */ 141 | val = ntv2_reg_read(ntv2_chn->vid_reg, ntv2_kona_reg_audio_source, index); 142 | org_source = NTV2_FLD_GET(ntv2_kona_fld_audio_input_ch12, val); 143 | org_bit0 = NTV2_FLD_GET(ntv2_kona_fld_audio_embedded_input_b0, val); 144 | org_bit1 = NTV2_FLD_GET(ntv2_kona_fld_audio_embedded_input_b1, val); 145 | 146 | /* handle auto source */ 147 | if (stream->audio.source_format.type == ntv2_input_type_auto) { 148 | /* if video source use for audio */ 149 | video_stream = ntv2_chn->streams[ntv2_stream_type_vidin]; 150 | if (video_stream != NULL) { 151 | source_config = ntv2_features_find_source_config( 152 | features, 153 | index, 154 | video_stream->video.input_format.type, 155 | video_stream->video.input_format.input_index); 156 | if (source_config != NULL) { 157 | ntv2_features_gen_source_format(source_config, &source_format); 158 | NTV2_MSG_CHANNEL_STATE("%s: audio auto route to video %s\n", 159 | ntv2_chn->name, source_config->name); 160 | } else { 161 | /* if no audio source use default */ 162 | source_format = stream->audio.auto_format; 163 | NTV2_MSG_CHANNEL_STATE("%s: audio auto route default\n", 164 | ntv2_chn->name); 165 | } 166 | } else { 167 | /* if no video source use default */ 168 | source_format = stream->audio.auto_format; 169 | NTV2_MSG_CHANNEL_STATE("%s: audio auto route default\n", 170 | ntv2_chn->name); 171 | } 172 | } else { 173 | source_format = stream->audio.source_format; 174 | } 175 | 176 | new_source = source_format.audio_source; 177 | new_bit0 = source_format.input_index & 0x1; 178 | new_bit1 = (source_format.input_index & 0x2) >> 1; 179 | 180 | /* set audio source */ 181 | val = NTV2_FLD_SET(ntv2_kona_fld_audio_input_ch12, new_source); 182 | mask = NTV2_FLD_MASK(ntv2_kona_fld_audio_input_ch12); 183 | val |= NTV2_FLD_SET(ntv2_kona_fld_audio_input_ch34, new_source); 184 | mask |= NTV2_FLD_MASK(ntv2_kona_fld_audio_input_ch34); 185 | val |= NTV2_FLD_SET(ntv2_kona_fld_audio_input_ch56, new_source); 186 | mask |= NTV2_FLD_MASK(ntv2_kona_fld_audio_input_ch56); 187 | val |= NTV2_FLD_SET(ntv2_kona_fld_audio_input_ch78, new_source); 188 | mask |= NTV2_FLD_MASK(ntv2_kona_fld_audio_input_ch78); 189 | 190 | /* set sdi embedded / hdmi channel */ 191 | val |= NTV2_FLD_SET(ntv2_kona_fld_audio_embedded_input_b0, new_bit0); 192 | mask |= NTV2_FLD_MASK(ntv2_kona_fld_audio_embedded_input_b0); 193 | val |= NTV2_FLD_SET(ntv2_kona_fld_audio_embedded_input_b1, new_bit1); 194 | mask |= NTV2_FLD_MASK(ntv2_kona_fld_audio_embedded_input_b1); 195 | 196 | /* update source */ 197 | ntv2_reg_rmw(ntv2_chn->vid_reg, ntv2_kona_reg_audio_source, index, val, mask); 198 | 199 | /* if audio source changes then resync with video */ 200 | if ((new_source != org_source) || 201 | (new_bit0 != org_bit0) || 202 | (new_bit1 != org_bit1)) { 203 | stream->audio.ring_offset = 0x40000000; 204 | } 205 | 206 | return 0; 207 | } 208 | 209 | int ntv2_audioops_interrupt_capture(struct ntv2_channel_stream *stream) 210 | { 211 | struct ntv2_channel *ntv2_chn = stream->ntv2_chn; 212 | struct ntv2_channel_stream *video_stream = ntv2_chn->streams[ntv2_stream_type_vidin]; 213 | struct ntv2_stream_data *data_ready; 214 | int index = ntv2_chn->index; 215 | s64 stat_time = ntv2_chn->dpc_status.stat_time; 216 | s64 time_us; 217 | u32 prev_audio_offset; 218 | u32 audio_stride; 219 | u32 audio_offset; 220 | u32 ring_offset; 221 | u32 audio_delta_ring; 222 | u32 audio_delta_offset; 223 | u32 audio_delta = 0; 224 | u32 audio_samples; 225 | u32 audio_size; 226 | u32 ring_size = stream->audio.ring_size; 227 | u32 val; 228 | u32 mask; 229 | bool input_clock = false; 230 | bool embedded_clock = false; 231 | 232 | /* idle if not enabled */ 233 | if (!stream->queue_enable) 234 | return 0; 235 | 236 | /* if video input is enabled, run on the video input interrupt */ 237 | if ((video_stream != NULL) && video_stream->queue_enable) 238 | input_clock = true; 239 | 240 | /* for sdi and hdmi inputs use the generated embedded audio clock */ 241 | if ((video_stream->video.input_format.type == ntv2_input_type_sdi) || 242 | (video_stream->video.input_format.type == ntv2_input_type_hdmi_adv) || 243 | (video_stream->video.input_format.type == ntv2_input_type_hdmi_aja)) 244 | embedded_clock = true; 245 | 246 | /* if there are no reference inputs use the input interrupt */ 247 | if (stream->ntv2_chn->features->num_reference_inputs == 0) 248 | input_clock = true; 249 | 250 | /* only run on the correct interrupt */ 251 | if (input_clock) { 252 | if(!ntv2_chn->dpc_status.interrupt_input) 253 | return 0; 254 | } else { 255 | if(!ntv2_chn->dpc_status.interrupt_output) 256 | return 0; 257 | } 258 | 259 | /* set the embedded audio clock source for sdi sources */ 260 | if (embedded_clock) { 261 | if (!stream->audio.embedded_clock) { 262 | val = NTV2_FLD_SET(ntv2_kona_fld_audio_embedded_clock, 1); 263 | mask = NTV2_FLD_MASK(ntv2_kona_fld_audio_embedded_clock); 264 | ntv2_reg_rmw(ntv2_chn->vid_reg, ntv2_kona_reg_audio_source, index, val, mask); 265 | stream->audio.embedded_clock = true; 266 | } 267 | } else { 268 | if (stream->audio.embedded_clock) { 269 | val = NTV2_FLD_SET(ntv2_kona_fld_audio_embedded_clock, 0); 270 | mask = NTV2_FLD_MASK(ntv2_kona_fld_audio_embedded_clock); 271 | ntv2_reg_rmw(ntv2_chn->vid_reg, ntv2_kona_reg_audio_source, index, val, mask); 272 | stream->audio.embedded_clock = false; 273 | } 274 | } 275 | 276 | /* get dynamic stream time and audio position */ 277 | stream->timestamp = ntv2_chn->dpc_status.interrupt_time; 278 | audio_offset = ntv2_chn->dpc_status.audio_input_offset; 279 | 280 | /* align the current hardware audio offset */ 281 | audio_stride = stream->audio.num_channels * stream->audio.sample_size; 282 | audio_offset = audio_offset / audio_stride * audio_stride; 283 | 284 | /* offset the current hardware audio offset for frame buffer latency */ 285 | audio_offset = (audio_offset + ring_size - stream->audio.ring_init)%ring_size; 286 | 287 | /* compute expected sample bytes from last interrupt */ 288 | audio_samples = ntv2_audio_frame_samples(ntv2_chn->dpc_status.interrupt_rate, stream->audio.sync_cadence++); 289 | audio_size = audio_samples * audio_stride; 290 | 291 | if (stream->queue_last) { 292 | prev_audio_offset = stream->audio.audio_offset; 293 | /* update computed ring offset */ 294 | ring_offset = (stream->audio.ring_offset + audio_size)%ring_size; 295 | /* check audio sync with hardware */ 296 | audio_delta_ring = (ring_offset + ring_size - audio_offset)%ring_size; 297 | audio_delta_offset = (audio_offset + ring_size - ring_offset)%ring_size; 298 | audio_delta = min(audio_delta_ring, audio_delta_offset); 299 | audio_delta = (audio_delta / audio_stride) * 10000 / stream->audio.sample_rate; 300 | if (audio_delta > (stream->audio.sync_tolerance/100)) { 301 | NTV2_MSG_CHANNEL_STATE("%s: %s correcting audio sync exp %08x act %08x error %d us\n", 302 | ntv2_chn->name, 303 | ntv2_stream_name(ntv2_stream_type_audin), 304 | ring_offset, 305 | audio_offset, 306 | audio_delta * 100); 307 | /* correct number of samples transfered */ 308 | audio_size += (s32)(stream->audio.total_sample_count - stream->audio.total_transfer_count) * (s32)audio_stride; 309 | /* limit in case of unexpected results */ 310 | if (audio_size > ring_size/4) 311 | audio_size = audio_samples * audio_stride; 312 | /* move the ring position to the hardware audio offset */ 313 | prev_audio_offset = (audio_offset + ring_size - audio_size)%ring_size; 314 | ring_offset = audio_offset; 315 | } 316 | /* save for stats */ 317 | stream->audio.total_sample_count += audio_samples; 318 | stream->audio.stat_sample_count += audio_samples; 319 | } else { 320 | /* set offset on start */ 321 | prev_audio_offset = audio_offset; 322 | ring_offset = audio_offset; 323 | /* initialize stats */ 324 | stream->audio.total_sample_count = 0; 325 | stream->audio.total_transfer_count = 0; 326 | stream->audio.total_drop_count = 0; 327 | stream->audio.stat_sample_count = 0; 328 | stream->audio.stat_drop_count = 0; 329 | stream->audio.last_display_time = stat_time; 330 | } 331 | 332 | /* save current audio offset */ 333 | stream->audio.audio_offset = audio_offset; 334 | stream->audio.ring_offset = ring_offset; 335 | 336 | #if 0 337 | NTV2_MSG_CHANNEL_STATE("%s: %s offset %d ring %d samples %d delta %d\n", 338 | ntv2_chn->name, 339 | ntv2_stream_name(stream->type), 340 | audio_offset, 341 | ring_offset, 342 | audio_samples, 343 | audio_delta); 344 | #endif 345 | 346 | /* add frame to queue */ 347 | if (stream->queue_run && (stream->audio.total_sample_count != 0)) { 348 | audio_size = (audio_offset + ring_size - prev_audio_offset)%ring_size; 349 | audio_samples = audio_size / audio_stride; 350 | 351 | if (!list_empty(&stream->data_done_list)) { 352 | /* get next data object */ 353 | data_ready = list_first_entry(&stream->data_done_list, 354 | struct ntv2_stream_data, list); 355 | list_del_init(&data_ready->list); 356 | /* add audio data to queue */ 357 | data_ready->audio.offset = prev_audio_offset; 358 | data_ready->audio.address[0] = stream->audio.ring_address + prev_audio_offset; 359 | data_ready->audio.address[1] = stream->audio.ring_address; 360 | if ((prev_audio_offset + audio_size) > ring_size) { 361 | data_ready->audio.data_size[0] = ring_size - prev_audio_offset; 362 | data_ready->audio.data_size[1] = audio_size - data_ready->audio.data_size[0]; 363 | } else { 364 | data_ready->audio.data_size[0] = audio_size; 365 | data_ready->audio.data_size[1] = 0; 366 | } 367 | data_ready->audio.num_channels = stream->audio.num_channels; 368 | data_ready->audio.sample_size = stream->audio.sample_size; 369 | 370 | list_add_tail(&data_ready->list, &stream->data_ready_list); 371 | NTV2_MSG_CHANNEL_STREAM("%s: audio capture data queue %d size %d\n", 372 | ntv2_chn->name, 373 | data_ready->index, 374 | audio_size); 375 | 376 | stream->audio.total_transfer_count += audio_samples; 377 | } else { 378 | stream->video.total_drop_count += audio_samples; 379 | stream->video.stat_drop_count += audio_samples; 380 | } 381 | } 382 | 383 | /* cache last enable state */ 384 | stream->queue_last = stream->queue_run; 385 | 386 | /* print statistics */ 387 | if (stream->audio.stat_sample_count != 0) { 388 | time_us = stat_time - stream->audio.last_display_time; 389 | if (time_us > NTV2_CHANNEL_STATISTIC_INTERVAL) 390 | { 391 | NTV2_MSG_CHANNEL_STATISTICS("%s: audio samples %4d drops %4d time %6d (us) total samples %lld transfers %lld drops %lld\n", 392 | ntv2_chn->name, 393 | (u32)(stream->audio.stat_sample_count), 394 | (u32)(stream->audio.stat_drop_count), 395 | (u32)(time_us / stream->audio.stat_sample_count), 396 | stream->audio.total_sample_count, 397 | stream->audio.total_transfer_count, 398 | stream->audio.total_drop_count); 399 | 400 | stream->audio.stat_sample_count = 0; 401 | stream->audio.stat_drop_count = 0; 402 | stream->audio.last_display_time = stat_time; 403 | } 404 | } 405 | 406 | return 0; 407 | } 408 | --------------------------------------------------------------------------------