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