2019-05-27 08:55:06 +02:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
2010-06-17 13:27:26 -04:00
/*
2020-07-08 08:24:20 +02:00
* Copyright ( C ) 2010 - 2013 Bluecherry , LLC < https : //www.bluecherrydvr.com>
2013-03-25 05:35:17 -03:00
*
* Original author :
* Ben Collins < bcollins @ ubuntu . com >
*
* Additional work by :
* John Brooks < john . brooks @ bluecherry . net >
2010-06-17 13:27:26 -04:00
*/
2011-02-11 13:38:20 +01:00
# ifndef __SOLO6X10_H
# define __SOLO6X10_H
2010-06-17 13:27:26 -04:00
# include <linux/pci.h>
# include <linux/i2c.h>
# include <linux/mutex.h>
# include <linux/list.h>
# include <linux/wait.h>
2013-03-25 05:35:17 -03:00
# include <linux/stringify.h>
# include <linux/io.h>
2011-07-26 16:09:06 -07:00
# include <linux/atomic.h>
2013-03-25 05:35:17 -03:00
# include <linux/slab.h>
2010-06-17 13:27:26 -04:00
# include <linux/videodev2.h>
2017-08-02 10:17:02 -04:00
# include <linux/gpio/driver.h>
2013-03-25 05:35:17 -03:00
2010-06-17 13:27:26 -04:00
# include <media/v4l2-dev.h>
2013-03-25 05:36:44 -03:00
# include <media/v4l2-device.h>
2013-03-25 05:38:14 -03:00
# include <media/v4l2-ctrls.h>
2015-09-22 10:30:29 -03:00
# include <media/videobuf2-v4l2.h>
2013-03-25 05:35:17 -03:00
2013-03-25 05:42:46 -03:00
# include "solo6x10-regs.h"
2010-06-17 13:27:26 -04:00
# ifndef PCI_VENDOR_ID_SOFTLOGIC
# define PCI_VENDOR_ID_SOFTLOGIC 0x9413
# define PCI_DEVICE_ID_SOLO6010 0x6010
2011-02-11 13:32:11 +01:00
# define PCI_DEVICE_ID_SOLO6110 0x6110
2010-06-17 13:27:26 -04:00
# endif
# ifndef PCI_VENDOR_ID_BLUECHERRY
# define PCI_VENDOR_ID_BLUECHERRY 0x1BB3
/* Neugent Softlogic 6010 based cards */
# define PCI_DEVICE_ID_NEUSOLO_4 0x4304
# define PCI_DEVICE_ID_NEUSOLO_9 0x4309
# define PCI_DEVICE_ID_NEUSOLO_16 0x4310
2010-11-04 22:51:17 -04:00
/* Bluecherry Softlogic 6010 based cards */
# define PCI_DEVICE_ID_BC_SOLO_4 0x4E04
# define PCI_DEVICE_ID_BC_SOLO_9 0x4E09
# define PCI_DEVICE_ID_BC_SOLO_16 0x4E10
/* Bluecherry Softlogic 6110 based cards */
# define PCI_DEVICE_ID_BC_6110_4 0x5304
# define PCI_DEVICE_ID_BC_6110_8 0x5308
# define PCI_DEVICE_ID_BC_6110_16 0x5310
2010-06-17 13:27:26 -04:00
# endif /* Bluecherry */
2013-03-25 05:35:17 -03:00
/* Used in pci_device_id, and solo_dev->type */
# define SOLO_DEV_6010 0
# define SOLO_DEV_6110 1
2011-02-11 13:38:20 +01:00
# define SOLO6X10_NAME "solo6x10"
2010-06-17 13:27:26 -04:00
# define SOLO_MAX_CHANNELS 16
2013-03-12 18:03:20 -03:00
# define SOLO6X10_VERSION "3.0.0"
2011-02-11 13:32:11 +01:00
2010-06-17 13:27:26 -04:00
/*
2011-02-11 13:38:20 +01:00
* The SOLO6x10 actually has 8 i2c channels , but we only use 2.
2010-06-17 13:27:26 -04:00
* 0 - Techwell chip ( s )
* 1 - SAA7128
*/
# define SOLO_I2C_ADAPTERS 2
# define SOLO_I2C_TW 0
# define SOLO_I2C_SAA 1
/* DMA Engine setup */
# define SOLO_NR_P2M 4
# define SOLO_NR_P2M_DESC 256
2013-03-25 05:35:17 -03:00
# define SOLO_P2M_DESC_SIZE (SOLO_NR_P2M_DESC * 16)
2010-06-17 13:27:26 -04:00
/* Encoder standard modes */
# define SOLO_ENC_MODE_CIF 2
# define SOLO_ENC_MODE_HD1 1
# define SOLO_ENC_MODE_D1 9
# define SOLO_DEFAULT_QP 3
2013-03-25 05:38:14 -03:00
# define SOLO_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)
# define V4L2_CID_MOTION_TRACE (SOLO_CID_CUSTOM_BASE+2)
# define V4L2_CID_OSD_TEXT (SOLO_CID_CUSTOM_BASE+3)
2010-06-17 13:27:26 -04:00
2013-03-18 08:43:14 -03:00
/*
* Motion thresholds are in a table of 64 x64 samples , with
* each sample representing 16 x16 pixels of the source . In
* effect , 44 x30 samples are used for NTSC , and 44 x36 for PAL .
* The 5 th sample on the 10 th row is ( 10 * 64 ) + 5 = 645.
2013-03-29 07:20:36 -03:00
*
2014-06-10 07:37:30 -03:00
* Internally it is stored as a 45 x45 array ( 45 * 16 = 720 , which is the
* maximum PAL / NTSC width ) .
2013-03-18 08:43:14 -03:00
*/
2013-03-29 07:20:36 -03:00
# define SOLO_MOTION_SZ (45)
2013-03-18 08:43:14 -03:00
2010-06-17 13:27:26 -04:00
enum SOLO_I2C_STATE {
IIC_STATE_IDLE ,
IIC_STATE_START ,
IIC_STATE_READ ,
IIC_STATE_WRITE ,
IIC_STATE_STOP
} ;
2013-03-25 05:35:17 -03:00
/* Defined in Table 4-16, Page 68-69 of the 6010 Datasheet */
struct solo_p2m_desc {
u32 ctrl ;
u32 cfg ;
u32 dma_addr ;
u32 ext_addr ;
2010-11-04 22:51:17 -04:00
} ;
2010-06-17 13:27:26 -04:00
struct solo_p2m_dev {
2010-11-04 22:51:17 -04:00
struct mutex mutex ;
2010-06-17 13:27:26 -04:00
struct completion completion ;
2013-03-25 05:35:17 -03:00
int desc_count ;
int desc_idx ;
struct solo_p2m_desc * descs ;
2010-06-17 13:27:26 -04:00
int error ;
} ;
2013-03-25 05:35:17 -03:00
# define OSD_TEXT_MAX 44
2010-06-17 13:27:26 -04:00
2013-03-15 12:04:14 -03:00
struct solo_vb2_buf {
[media] media: videobuf2: Restructure vb2_buffer
Remove v4l2 stuff - v4l2_buf, v4l2_plane - from struct vb2_buffer.
Add new member variables - bytesused, length, offset, userptr, fd,
data_offset - to struct vb2_plane in order to cover all information
of v4l2_plane.
struct vb2_plane {
<snip>
unsigned int bytesused;
unsigned int length;
union {
unsigned int offset;
unsigned long userptr;
int fd;
} m;
unsigned int data_offset;
}
Replace v4l2_buf with new member variables - index, type, memory - which
are common fields for buffer management.
struct vb2_buffer {
<snip>
unsigned int index;
unsigned int type;
unsigned int memory;
unsigned int num_planes;
struct vb2_plane planes[VIDEO_MAX_PLANES];
<snip>
};
v4l2 specific fields - flags, field, timestamp, timecode,
sequence - are moved to vb2_v4l2_buffer in videobuf2-v4l2.c
struct vb2_v4l2_buffer {
struct vb2_buffer vb2_buf;
__u32 flags;
__u32 field;
struct timeval timestamp;
struct v4l2_timecode timecode;
__u32 sequence;
};
Signed-off-by: Junghak Sung <jh1009.sung@samsung.com>
Signed-off-by: Geunyoung Kim <nenggun.kim@samsung.com>
Acked-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2015-09-22 10:30:30 -03:00
struct vb2_v4l2_buffer vb ;
2013-03-15 12:04:14 -03:00
struct list_head list ;
} ;
2013-03-18 08:41:13 -03:00
enum solo_enc_types {
SOLO_ENC_TYPE_STD ,
SOLO_ENC_TYPE_EXT ,
} ;
2010-06-17 13:27:26 -04:00
struct solo_enc_dev {
2013-03-25 05:35:17 -03:00
struct solo_dev * solo_dev ;
2010-06-17 13:27:26 -04:00
/* V4L2 Items */
2013-03-25 05:38:14 -03:00
struct v4l2_ctrl_handler hdl ;
2014-06-10 07:37:30 -03:00
struct v4l2_ctrl * md_thresholds ;
2010-06-17 13:27:26 -04:00
struct video_device * vfd ;
/* General accounting */
2013-03-15 12:04:14 -03:00
struct mutex lock ;
2013-03-25 05:35:17 -03:00
spinlock_t motion_lock ;
2010-06-17 13:27:26 -04:00
u8 ch ;
u8 mode , gop , qp , interlaced , interval ;
u8 bw_weight ;
u16 motion_thresh ;
2013-03-18 08:43:14 -03:00
bool motion_global ;
bool motion_enabled ;
2010-06-17 13:27:26 -04:00
u16 width ;
u16 height ;
2013-03-25 05:35:17 -03:00
/* OSD buffers */
2010-06-17 13:27:26 -04:00
char osd_text [ OSD_TEXT_MAX + 1 ] ;
2013-03-25 05:35:17 -03:00
u8 osd_buf [ SOLO_EOSD_EXT_SIZE_MAX ]
__aligned ( 4 ) ;
2010-06-17 13:27:26 -04:00
2013-03-25 05:35:17 -03:00
/* VOP stuff */
2014-12-24 08:35:59 -03:00
u8 vop [ 64 ] ;
2013-03-25 05:35:17 -03:00
int vop_len ;
2014-12-24 08:35:59 -03:00
u8 jpeg_header [ 1024 ] ;
2013-03-25 05:35:17 -03:00
int jpeg_len ;
2013-03-18 08:41:13 -03:00
u32 fmt ;
enum solo_enc_types type ;
2013-03-15 13:16:49 -03:00
u32 sequence ;
2013-03-15 12:04:14 -03:00
struct vb2_queue vidq ;
2013-03-18 08:41:13 -03:00
struct list_head vidq_active ;
int desc_count ;
int desc_nelts ;
struct solo_p2m_desc * desc_items ;
dma_addr_t desc_dma ;
spinlock_t av_lock ;
2010-06-17 13:27:26 -04:00
} ;
2011-02-11 13:38:20 +01:00
/* The SOLO6x10 PCI Device */
struct solo_dev {
2010-06-17 13:27:26 -04:00
/* General stuff */
struct pci_dev * pdev ;
2013-03-25 05:35:17 -03:00
int type ;
unsigned int time_sync ;
unsigned int usec_lsb ;
unsigned int clock_mhz ;
2010-06-17 13:27:26 -04:00
u8 __iomem * reg_base ;
int nr_chans ;
int nr_ext ;
u32 irq_mask ;
u32 motion_mask ;
2013-03-25 05:36:44 -03:00
struct v4l2_device v4l2_dev ;
2017-08-02 10:17:02 -04:00
# ifdef CONFIG_GPIOLIB
/* GPIO */
struct gpio_chip gpio_dev ;
# endif
2010-06-17 13:27:26 -04:00
/* tw28xx accounting */
2010-06-22 22:32:01 -04:00
u8 tw2865 , tw2864 , tw2815 ;
2010-06-17 13:27:26 -04:00
u8 tw28_cnt ;
/* i2c related items */
struct i2c_adapter i2c_adap [ SOLO_I2C_ADAPTERS ] ;
enum SOLO_I2C_STATE i2c_state ;
2010-11-04 22:51:17 -04:00
struct mutex i2c_mutex ;
2010-06-17 13:27:26 -04:00
int i2c_id ;
wait_queue_head_t i2c_wait ;
struct i2c_msg * i2c_msg ;
unsigned int i2c_msg_num ;
unsigned int i2c_msg_ptr ;
/* P2M DMA Engine */
struct solo_p2m_dev p2m_dev [ SOLO_NR_P2M ] ;
2013-03-25 05:35:17 -03:00
atomic_t p2m_count ;
int p2m_jiffies ;
unsigned int p2m_timeouts ;
2010-06-17 13:27:26 -04:00
/* V4L2 Display items */
struct video_device * vfd ;
unsigned int erasing ;
unsigned int frame_blank ;
u8 cur_disp_ch ;
wait_queue_head_t disp_thread_wait ;
2013-03-25 05:38:14 -03:00
struct v4l2_ctrl_handler disp_hdl ;
2010-06-17 13:27:26 -04:00
/* V4L2 Encoder items */
struct solo_enc_dev * v4l2_enc [ SOLO_MAX_CHANNELS ] ;
u16 enc_bw_remain ;
/* IDX into hw mp4 encoder */
u8 enc_idx ;
/* Current video settings */
2010-11-10 10:39:33 -03:00
u32 video_type ;
2010-06-17 13:27:26 -04:00
u16 video_hsize , video_vsize ;
u16 vout_hstart , vout_vstart ;
u16 vin_hstart , vin_vstart ;
u8 fps ;
2013-03-25 05:35:17 -03:00
/* JPEG Qp setting */
spinlock_t jpeg_qp_lock ;
u32 jpeg_qp [ 2 ] ;
2010-06-17 13:27:26 -04:00
/* Audio components */
struct snd_card * snd_card ;
struct snd_pcm * snd_pcm ;
atomic_t snd_users ;
int g723_hw_idx ;
2013-03-25 05:35:17 -03:00
/* sysfs stuffs */
struct device dev ;
int sdram_size ;
struct bin_attribute sdram_attr ;
unsigned int sys_config ;
/* Ring thread */
struct task_struct * ring_thread ;
wait_queue_head_t ring_thread_wait ;
/* VOP_HEADER handling */
void * vh_buf ;
dma_addr_t vh_dma ;
int vh_size ;
2013-03-15 11:56:46 -03:00
/* Buffer handling */
2013-03-15 12:11:17 -03:00
struct vb2_queue vidq ;
2013-03-15 13:16:49 -03:00
u32 sequence ;
2013-03-15 11:56:46 -03:00
struct task_struct * kthread ;
2013-03-15 12:11:17 -03:00
struct mutex lock ;
2013-03-15 11:56:46 -03:00
spinlock_t slock ;
int old_write ;
struct list_head vidq_active ;
2010-06-17 13:27:26 -04:00
} ;
2011-02-11 13:38:20 +01:00
static inline u32 solo_reg_read ( struct solo_dev * solo_dev , int reg )
2010-06-17 13:27:26 -04:00
{
2015-06-08 10:42:24 -03:00
return readl ( solo_dev - > reg_base + reg ) ;
2010-06-17 13:27:26 -04:00
}
2013-03-25 05:35:17 -03:00
static inline void solo_reg_write ( struct solo_dev * solo_dev , int reg ,
u32 data )
2010-06-17 13:27:26 -04:00
{
2016-10-22 13:34:36 -02:00
u16 val ;
2010-06-17 13:27:26 -04:00
writel ( data , solo_dev - > reg_base + reg ) ;
2016-10-22 13:34:36 -02:00
pci_read_config_word ( solo_dev - > pdev , PCI_STATUS , & val ) ;
2010-06-17 13:27:26 -04:00
}
2013-03-25 05:35:17 -03:00
static inline void solo_irq_on ( struct solo_dev * dev , u32 mask )
{
dev - > irq_mask | = mask ;
solo_reg_write ( dev , SOLO_IRQ_MASK , dev - > irq_mask ) ;
}
static inline void solo_irq_off ( struct solo_dev * dev , u32 mask )
{
dev - > irq_mask & = ~ mask ;
solo_reg_write ( dev , SOLO_IRQ_MASK , dev - > irq_mask ) ;
}
2010-06-17 13:27:26 -04:00
2013-03-15 12:53:17 -03:00
/* Init/exit routines for subsystems */
2011-02-11 13:38:20 +01:00
int solo_disp_init ( struct solo_dev * solo_dev ) ;
void solo_disp_exit ( struct solo_dev * solo_dev ) ;
2010-06-17 13:27:26 -04:00
2011-02-11 13:38:20 +01:00
int solo_gpio_init ( struct solo_dev * solo_dev ) ;
void solo_gpio_exit ( struct solo_dev * solo_dev ) ;
2010-06-17 13:27:26 -04:00
2011-02-11 13:38:20 +01:00
int solo_i2c_init ( struct solo_dev * solo_dev ) ;
void solo_i2c_exit ( struct solo_dev * solo_dev ) ;
2010-06-17 13:27:26 -04:00
2011-02-11 13:38:20 +01:00
int solo_p2m_init ( struct solo_dev * solo_dev ) ;
void solo_p2m_exit ( struct solo_dev * solo_dev ) ;
2010-06-17 13:27:26 -04:00
2013-03-25 05:35:17 -03:00
int solo_v4l2_init ( struct solo_dev * solo_dev , unsigned nr ) ;
2011-02-11 13:38:20 +01:00
void solo_v4l2_exit ( struct solo_dev * solo_dev ) ;
2010-06-17 13:27:26 -04:00
2011-02-11 13:38:20 +01:00
int solo_enc_init ( struct solo_dev * solo_dev ) ;
void solo_enc_exit ( struct solo_dev * solo_dev ) ;
2010-06-17 13:27:26 -04:00
2013-03-25 05:35:17 -03:00
int solo_enc_v4l2_init ( struct solo_dev * solo_dev , unsigned nr ) ;
2011-02-11 13:38:20 +01:00
void solo_enc_v4l2_exit ( struct solo_dev * solo_dev ) ;
2010-06-17 13:27:26 -04:00
2011-02-11 13:38:20 +01:00
int solo_g723_init ( struct solo_dev * solo_dev ) ;
void solo_g723_exit ( struct solo_dev * solo_dev ) ;
2010-06-17 13:27:26 -04:00
/* ISR's */
2011-02-11 13:38:20 +01:00
int solo_i2c_isr ( struct solo_dev * solo_dev ) ;
void solo_p2m_isr ( struct solo_dev * solo_dev , int id ) ;
2013-03-25 05:35:17 -03:00
void solo_p2m_error_isr ( struct solo_dev * solo_dev ) ;
2011-02-11 13:38:20 +01:00
void solo_enc_v4l2_isr ( struct solo_dev * solo_dev ) ;
void solo_g723_isr ( struct solo_dev * solo_dev ) ;
void solo_motion_isr ( struct solo_dev * solo_dev ) ;
void solo_video_in_isr ( struct solo_dev * solo_dev ) ;
2010-06-17 13:27:26 -04:00
/* i2c read/write */
2011-02-11 13:38:20 +01:00
u8 solo_i2c_readbyte ( struct solo_dev * solo_dev , int id , u8 addr , u8 off ) ;
void solo_i2c_writebyte ( struct solo_dev * solo_dev , int id , u8 addr , u8 off ,
2010-06-17 13:27:26 -04:00
u8 data ) ;
/* P2M DMA */
2013-03-25 05:35:17 -03:00
int solo_p2m_dma_t ( struct solo_dev * solo_dev , int wr ,
dma_addr_t dma_addr , u32 ext_addr , u32 size ,
int repeat , u32 ext_size ) ;
int solo_p2m_dma ( struct solo_dev * solo_dev , int wr ,
void * sys_addr , u32 ext_addr , u32 size ,
int repeat , u32 ext_size ) ;
void solo_p2m_fill_desc ( struct solo_p2m_desc * desc , int wr ,
dma_addr_t dma_addr , u32 ext_addr , u32 size ,
int repeat , u32 ext_size ) ;
int solo_p2m_dma_desc ( struct solo_dev * solo_dev ,
struct solo_p2m_desc * desc , dma_addr_t desc_dma ,
int desc_cnt ) ;
2010-06-17 13:27:26 -04:00
2013-03-15 12:53:17 -03:00
/* Global s_std ioctl */
2014-01-13 06:58:12 -03:00
int solo_set_video_type ( struct solo_dev * solo_dev , bool is_50hz ) ;
2013-03-15 12:53:17 -03:00
void solo_update_mode ( struct solo_enc_dev * solo_enc ) ;
2010-06-17 13:27:26 -04:00
/* Set the threshold for motion detection */
2013-03-25 05:35:17 -03:00
int solo_set_motion_threshold ( struct solo_dev * solo_dev , u8 ch , u16 val ) ;
2013-03-18 08:43:14 -03:00
int solo_set_motion_block ( struct solo_dev * solo_dev , u8 ch ,
2014-06-10 07:37:30 -03:00
const u16 * thresholds ) ;
2010-06-17 13:27:26 -04:00
# define SOLO_DEF_MOT_THRESH 0x0300
/* Write text on OSD */
int solo_osd_print ( struct solo_enc_dev * solo_enc ) ;
2013-03-25 05:35:17 -03:00
/* EEPROM commands */
unsigned int solo_eeprom_ewen ( struct solo_dev * solo_dev , int w_en ) ;
2014-08-20 16:27:38 -03:00
__be16 solo_eeprom_read ( struct solo_dev * solo_dev , int loc ) ;
2013-03-25 05:35:17 -03:00
int solo_eeprom_write ( struct solo_dev * solo_dev , int loc ,
2014-08-20 16:27:38 -03:00
__be16 data ) ;
2013-03-25 05:35:17 -03:00
/* JPEG Qp functions */
void solo_s_jpeg_qp ( struct solo_dev * solo_dev , unsigned int ch ,
unsigned int qp ) ;
int solo_g_jpeg_qp ( struct solo_dev * solo_dev , unsigned int ch ) ;
# define CHK_FLAGS(v, flags) (((v) & (flags)) == (flags))
2011-02-11 13:38:20 +01:00
# endif /* __SOLO6X10_H */