xref: /OK3568_Linux_fs/kernel/drivers/media/pci/tw686x/tw686x.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2015 VanguardiaSur - www.vanguardiasur.com.ar
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2015 Industrial Research Institute for Automation
6*4882a593Smuzhiyun  * and Measurements PIAP
7*4882a593Smuzhiyun  * Written by Krzysztof Ha?asa
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/mutex.h>
11*4882a593Smuzhiyun #include <linux/pci.h>
12*4882a593Smuzhiyun #include <linux/timer.h>
13*4882a593Smuzhiyun #include <linux/videodev2.h>
14*4882a593Smuzhiyun #include <media/v4l2-common.h>
15*4882a593Smuzhiyun #include <media/v4l2-ctrls.h>
16*4882a593Smuzhiyun #include <media/v4l2-device.h>
17*4882a593Smuzhiyun #include <media/v4l2-ioctl.h>
18*4882a593Smuzhiyun #include <media/videobuf2-v4l2.h>
19*4882a593Smuzhiyun #include <sound/pcm.h>
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #include "tw686x-regs.h"
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #define TYPE_MAX_CHANNELS	0x0f
24*4882a593Smuzhiyun #define TYPE_SECOND_GEN		0x10
25*4882a593Smuzhiyun #define TW686X_DEF_PHASE_REF	0x1518
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #define TW686X_AUDIO_PAGE_MAX		16
28*4882a593Smuzhiyun #define TW686X_AUDIO_PERIODS_MIN	2
29*4882a593Smuzhiyun #define TW686X_AUDIO_PERIODS_MAX	TW686X_AUDIO_PAGE_MAX
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #define TW686X_DMA_MODE_MEMCPY		0
32*4882a593Smuzhiyun #define TW686X_DMA_MODE_CONTIG		1
33*4882a593Smuzhiyun #define TW686X_DMA_MODE_SG		2
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun struct tw686x_format {
36*4882a593Smuzhiyun 	char *name;
37*4882a593Smuzhiyun 	unsigned int fourcc;
38*4882a593Smuzhiyun 	unsigned int depth;
39*4882a593Smuzhiyun 	unsigned int mode;
40*4882a593Smuzhiyun };
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun struct tw686x_dma_desc {
43*4882a593Smuzhiyun 	dma_addr_t phys;
44*4882a593Smuzhiyun 	void *virt;
45*4882a593Smuzhiyun 	unsigned int size;
46*4882a593Smuzhiyun };
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun struct tw686x_sg_desc {
49*4882a593Smuzhiyun 	/* 3 MSBits for flags, 13 LSBits for length */
50*4882a593Smuzhiyun 	__le32 flags_length;
51*4882a593Smuzhiyun 	__le32 phys;
52*4882a593Smuzhiyun };
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun struct tw686x_audio_buf {
55*4882a593Smuzhiyun 	dma_addr_t dma;
56*4882a593Smuzhiyun 	void *virt;
57*4882a593Smuzhiyun 	struct list_head list;
58*4882a593Smuzhiyun };
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun struct tw686x_v4l2_buf {
61*4882a593Smuzhiyun 	struct vb2_v4l2_buffer vb;
62*4882a593Smuzhiyun 	struct list_head list;
63*4882a593Smuzhiyun };
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun struct tw686x_audio_channel {
66*4882a593Smuzhiyun 	struct tw686x_dev *dev;
67*4882a593Smuzhiyun 	struct snd_pcm_substream *ss;
68*4882a593Smuzhiyun 	unsigned int ch;
69*4882a593Smuzhiyun 	struct tw686x_audio_buf *curr_bufs[2];
70*4882a593Smuzhiyun 	struct tw686x_dma_desc dma_descs[2];
71*4882a593Smuzhiyun 	dma_addr_t ptr;
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	struct tw686x_audio_buf buf[TW686X_AUDIO_PAGE_MAX];
74*4882a593Smuzhiyun 	struct list_head buf_list;
75*4882a593Smuzhiyun 	spinlock_t lock;
76*4882a593Smuzhiyun };
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun struct tw686x_video_channel {
79*4882a593Smuzhiyun 	struct tw686x_dev *dev;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	struct vb2_queue vidq;
82*4882a593Smuzhiyun 	struct list_head vidq_queued;
83*4882a593Smuzhiyun 	struct video_device *device;
84*4882a593Smuzhiyun 	struct tw686x_v4l2_buf *curr_bufs[2];
85*4882a593Smuzhiyun 	struct tw686x_dma_desc dma_descs[2];
86*4882a593Smuzhiyun 	struct tw686x_sg_desc *sg_descs[2];
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	struct v4l2_ctrl_handler ctrl_handler;
89*4882a593Smuzhiyun 	const struct tw686x_format *format;
90*4882a593Smuzhiyun 	struct mutex vb_mutex;
91*4882a593Smuzhiyun 	spinlock_t qlock;
92*4882a593Smuzhiyun 	v4l2_std_id video_standard;
93*4882a593Smuzhiyun 	unsigned int width, height;
94*4882a593Smuzhiyun 	unsigned int h_halve, v_halve;
95*4882a593Smuzhiyun 	unsigned int ch;
96*4882a593Smuzhiyun 	unsigned int num;
97*4882a593Smuzhiyun 	unsigned int fps;
98*4882a593Smuzhiyun 	unsigned int input;
99*4882a593Smuzhiyun 	unsigned int sequence;
100*4882a593Smuzhiyun 	unsigned int pb;
101*4882a593Smuzhiyun 	bool no_signal;
102*4882a593Smuzhiyun };
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun struct tw686x_dma_ops {
105*4882a593Smuzhiyun 	int (*setup)(struct tw686x_dev *dev);
106*4882a593Smuzhiyun 	int (*alloc)(struct tw686x_video_channel *vc, unsigned int pb);
107*4882a593Smuzhiyun 	void (*free)(struct tw686x_video_channel *vc, unsigned int pb);
108*4882a593Smuzhiyun 	void (*buf_refill)(struct tw686x_video_channel *vc, unsigned int pb);
109*4882a593Smuzhiyun 	const struct vb2_mem_ops *mem_ops;
110*4882a593Smuzhiyun 	enum v4l2_field field;
111*4882a593Smuzhiyun 	u32 hw_dma_mode;
112*4882a593Smuzhiyun };
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun /**
115*4882a593Smuzhiyun  * struct tw686x_dev - global device status
116*4882a593Smuzhiyun  * @lock: spinlock controlling access to the
117*4882a593Smuzhiyun  *        shared device registers (DMA enable/disable).
118*4882a593Smuzhiyun  */
119*4882a593Smuzhiyun struct tw686x_dev {
120*4882a593Smuzhiyun 	spinlock_t lock;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	struct v4l2_device v4l2_dev;
123*4882a593Smuzhiyun 	struct snd_card *snd_card;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	char name[32];
126*4882a593Smuzhiyun 	unsigned int type;
127*4882a593Smuzhiyun 	unsigned int dma_mode;
128*4882a593Smuzhiyun 	struct pci_dev *pci_dev;
129*4882a593Smuzhiyun 	__u32 __iomem *mmio;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	const struct tw686x_dma_ops *dma_ops;
132*4882a593Smuzhiyun 	struct tw686x_video_channel *video_channels;
133*4882a593Smuzhiyun 	struct tw686x_audio_channel *audio_channels;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	/* Per-device audio parameters */
136*4882a593Smuzhiyun 	int audio_rate;
137*4882a593Smuzhiyun 	int period_size;
138*4882a593Smuzhiyun 	int audio_enabled;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	struct timer_list dma_delay_timer;
141*4882a593Smuzhiyun 	u32 pending_dma_en; /* must be protected by lock */
142*4882a593Smuzhiyun 	u32 pending_dma_cmd; /* must be protected by lock */
143*4882a593Smuzhiyun };
144*4882a593Smuzhiyun 
reg_read(struct tw686x_dev * dev,unsigned int reg)145*4882a593Smuzhiyun static inline uint32_t reg_read(struct tw686x_dev *dev, unsigned int reg)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun 	return readl(dev->mmio + reg);
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun 
reg_write(struct tw686x_dev * dev,unsigned int reg,uint32_t value)150*4882a593Smuzhiyun static inline void reg_write(struct tw686x_dev *dev, unsigned int reg,
151*4882a593Smuzhiyun 			     uint32_t value)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun 	writel(value, dev->mmio + reg);
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun 
max_channels(struct tw686x_dev * dev)156*4882a593Smuzhiyun static inline unsigned int max_channels(struct tw686x_dev *dev)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun 	return dev->type & TYPE_MAX_CHANNELS; /* 4 or 8 channels */
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun 
is_second_gen(struct tw686x_dev * dev)161*4882a593Smuzhiyun static inline unsigned is_second_gen(struct tw686x_dev *dev)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun 	/* each channel has its own DMA SG table */
164*4882a593Smuzhiyun 	return dev->type & TYPE_SECOND_GEN;
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun void tw686x_enable_channel(struct tw686x_dev *dev, unsigned int channel);
168*4882a593Smuzhiyun void tw686x_disable_channel(struct tw686x_dev *dev, unsigned int channel);
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun int tw686x_video_init(struct tw686x_dev *dev);
171*4882a593Smuzhiyun void tw686x_video_free(struct tw686x_dev *dev);
172*4882a593Smuzhiyun void tw686x_video_irq(struct tw686x_dev *dev, unsigned long requests,
173*4882a593Smuzhiyun 		      unsigned int pb_status, unsigned int fifo_status,
174*4882a593Smuzhiyun 		      unsigned int *reset_ch);
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun int tw686x_audio_init(struct tw686x_dev *dev);
177*4882a593Smuzhiyun void tw686x_audio_free(struct tw686x_dev *dev);
178*4882a593Smuzhiyun void tw686x_audio_irq(struct tw686x_dev *dev, unsigned long requests,
179*4882a593Smuzhiyun 		      unsigned int pb_status);
180