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