Diff markup
1 #include <media/saa7146_vv.h> 1 #include <media/saa7146_vv.h>
>> 2 #include <linux/version.h>
2 3
3 #define BOARD_CAN_DO_VBI(dev) (dev->revision !! 4 #define BOARD_CAN_DO_VBI(dev) (dev->revision != 0 && dev->vv_data->vbi_minor != -1)
4 5
5 /********************************************* 6 /****************************************************************************/
6 /* resource management functions, shamelessly 7 /* resource management functions, shamelessly stolen from saa7134 driver */
7 8
8 int saa7146_res_get(struct saa7146_fh *fh, uns 9 int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit)
9 { 10 {
10 struct saa7146_dev *dev = fh->dev; 11 struct saa7146_dev *dev = fh->dev;
11 struct saa7146_vv *vv = dev->vv_data; 12 struct saa7146_vv *vv = dev->vv_data;
12 13
13 if (fh->resources & bit) { 14 if (fh->resources & bit) {
14 DEB_D(("already allocated! wan 15 DEB_D(("already allocated! want: 0x%02x, cur:0x%02x\n",bit,vv->resources));
15 /* have it already allocated * 16 /* have it already allocated */
16 return 1; 17 return 1;
17 } 18 }
18 19
19 /* is it free? */ 20 /* is it free? */
20 mutex_lock(&dev->lock); !! 21 down(&dev->lock);
21 if (vv->resources & bit) { 22 if (vv->resources & bit) {
22 DEB_D(("locked! vv->resources: 23 DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit));
23 /* no, someone else uses it */ 24 /* no, someone else uses it */
24 mutex_unlock(&dev->lock); !! 25 up(&dev->lock);
25 return 0; 26 return 0;
26 } 27 }
27 /* it's free, grab it */ 28 /* it's free, grab it */
28 fh->resources |= bit; 29 fh->resources |= bit;
29 vv->resources |= bit; 30 vv->resources |= bit;
30 DEB_D(("res: get 0x%02x, cur:0x%02x\n" 31 DEB_D(("res: get 0x%02x, cur:0x%02x\n",bit,vv->resources));
31 mutex_unlock(&dev->lock); !! 32 up(&dev->lock);
32 return 1; 33 return 1;
33 } 34 }
34 35
35 void saa7146_res_free(struct saa7146_fh *fh, u 36 void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
36 { 37 {
37 struct saa7146_dev *dev = fh->dev; 38 struct saa7146_dev *dev = fh->dev;
38 struct saa7146_vv *vv = dev->vv_data; 39 struct saa7146_vv *vv = dev->vv_data;
39 40
40 BUG_ON((fh->resources & bits) != bits) !! 41 if ((fh->resources & bits) != bits)
>> 42 BUG();
41 43
42 mutex_lock(&dev->lock); !! 44 down(&dev->lock);
43 fh->resources &= ~bits; 45 fh->resources &= ~bits;
44 vv->resources &= ~bits; 46 vv->resources &= ~bits;
45 DEB_D(("res: put 0x%02x, cur:0x%02x\n" 47 DEB_D(("res: put 0x%02x, cur:0x%02x\n",bits,vv->resources));
46 mutex_unlock(&dev->lock); !! 48 up(&dev->lock);
47 } 49 }
48 50
49 51
50 /********************************************* 52 /********************************************************************************/
51 /* common dma functions */ 53 /* common dma functions */
52 54
53 void saa7146_dma_free(struct saa7146_dev *dev, !! 55 void saa7146_dma_free(struct saa7146_dev *dev,struct saa7146_buf *buf)
54 <<
55 { 56 {
56 struct videobuf_dmabuf *dma=videobuf_t <<
57 DEB_EE(("dev:%p, buf:%p\n",dev,buf)); 57 DEB_EE(("dev:%p, buf:%p\n",dev,buf));
58 58
59 BUG_ON(in_interrupt()); !! 59 if (in_interrupt())
>> 60 BUG();
60 61
61 videobuf_waiton(&buf->vb,0,0); 62 videobuf_waiton(&buf->vb,0,0);
62 videobuf_dma_unmap(q, dma); !! 63 videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
63 videobuf_dma_free(dma); !! 64 videobuf_dma_free(&buf->vb.dma);
64 buf->vb.state = VIDEOBUF_NEEDS_INIT; !! 65 buf->vb.state = STATE_NEEDS_INIT;
65 } 66 }
66 67
67 68
68 /********************************************* 69 /********************************************************************************/
69 /* common buffer functions */ 70 /* common buffer functions */
70 71
71 int saa7146_buffer_queue(struct saa7146_dev *d 72 int saa7146_buffer_queue(struct saa7146_dev *dev,
72 struct saa7146_dmaque 73 struct saa7146_dmaqueue *q,
73 struct saa7146_buf *b 74 struct saa7146_buf *buf)
74 { 75 {
75 assert_spin_locked(&dev->slock); 76 assert_spin_locked(&dev->slock);
76 DEB_EE(("dev:%p, dmaq:%p, buf:%p\n", d 77 DEB_EE(("dev:%p, dmaq:%p, buf:%p\n", dev, q, buf));
77 78
78 BUG_ON(!q); 79 BUG_ON(!q);
79 80
80 if (NULL == q->curr) { 81 if (NULL == q->curr) {
81 q->curr = buf; 82 q->curr = buf;
82 DEB_D(("immediately activating 83 DEB_D(("immediately activating buffer %p\n", buf));
83 buf->activate(dev,buf,NULL); 84 buf->activate(dev,buf,NULL);
84 } else { 85 } else {
85 list_add_tail(&buf->vb.queue,& 86 list_add_tail(&buf->vb.queue,&q->queue);
86 buf->vb.state = VIDEOBUF_QUEUE !! 87 buf->vb.state = STATE_QUEUED;
87 DEB_D(("adding buffer %p to qu 88 DEB_D(("adding buffer %p to queue. (active buffer present)\n", buf));
88 } 89 }
89 return 0; 90 return 0;
90 } 91 }
91 92
92 void saa7146_buffer_finish(struct saa7146_dev 93 void saa7146_buffer_finish(struct saa7146_dev *dev,
93 struct saa7146_dmaq 94 struct saa7146_dmaqueue *q,
94 int state) 95 int state)
95 { 96 {
96 assert_spin_locked(&dev->slock); 97 assert_spin_locked(&dev->slock);
97 DEB_EE(("dev:%p, dmaq:%p, state:%d\n", 98 DEB_EE(("dev:%p, dmaq:%p, state:%d\n", dev, q, state));
98 DEB_EE(("q->curr:%p\n",q->curr)); 99 DEB_EE(("q->curr:%p\n",q->curr));
99 100
100 BUG_ON(!q->curr); 101 BUG_ON(!q->curr);
101 102
102 /* finish current buffer */ 103 /* finish current buffer */
103 if (NULL == q->curr) { 104 if (NULL == q->curr) {
104 DEB_D(("aiii. no current buffe 105 DEB_D(("aiii. no current buffer\n"));
105 return; !! 106 return;
106 } 107 }
107 !! 108
108 q->curr->vb.state = state; 109 q->curr->vb.state = state;
109 do_gettimeofday(&q->curr->vb.ts); 110 do_gettimeofday(&q->curr->vb.ts);
110 wake_up(&q->curr->vb.done); 111 wake_up(&q->curr->vb.done);
111 112
112 q->curr = NULL; 113 q->curr = NULL;
113 } 114 }
114 115
115 void saa7146_buffer_next(struct saa7146_dev *d 116 void saa7146_buffer_next(struct saa7146_dev *dev,
116 struct saa7146_dmaque 117 struct saa7146_dmaqueue *q, int vbi)
117 { 118 {
118 struct saa7146_buf *buf,*next = NULL; 119 struct saa7146_buf *buf,*next = NULL;
119 120
120 BUG_ON(!q); 121 BUG_ON(!q);
121 122
122 DEB_INT(("dev:%p, dmaq:%p, vbi:%d\n", 123 DEB_INT(("dev:%p, dmaq:%p, vbi:%d\n", dev, q, vbi));
123 124
124 assert_spin_locked(&dev->slock); 125 assert_spin_locked(&dev->slock);
125 if (!list_empty(&q->queue)) { 126 if (!list_empty(&q->queue)) {
126 /* activate next one from queu 127 /* activate next one from queue */
127 buf = list_entry(q->queue.next 128 buf = list_entry(q->queue.next,struct saa7146_buf,vb.queue);
128 list_del(&buf->vb.queue); 129 list_del(&buf->vb.queue);
129 if (!list_empty(&q->queue)) 130 if (!list_empty(&q->queue))
130 next = list_entry(q->q 131 next = list_entry(q->queue.next,struct saa7146_buf, vb.queue);
131 q->curr = buf; 132 q->curr = buf;
132 DEB_INT(("next buffer: buf:%p, 133 DEB_INT(("next buffer: buf:%p, prev:%p, next:%p\n", buf, q->queue.prev,q->queue.next));
133 buf->activate(dev,buf,next); 134 buf->activate(dev,buf,next);
134 } else { 135 } else {
135 DEB_INT(("no next buffer. stop 136 DEB_INT(("no next buffer. stopping.\n"));
136 if( 0 != vbi ) { 137 if( 0 != vbi ) {
137 /* turn off video-dma3 138 /* turn off video-dma3 */
138 saa7146_write(dev,MC1, 139 saa7146_write(dev,MC1, MASK_20);
139 } else { 140 } else {
140 /* nothing to do -- ju 141 /* nothing to do -- just prevent next video-dma1 transfer
141 by lowering the pro 142 by lowering the protection address */
142 143
143 // fixme: fix this for 144 // fixme: fix this for vflip != 0
144 145
145 saa7146_write(dev, PRO 146 saa7146_write(dev, PROT_ADDR1, 0);
146 saa7146_write(dev, MC2 !! 147 saa7146_write(dev, MC2, (MASK_02|MASK_18));
147 148
148 /* write the address o 149 /* write the address of the rps-program */
149 saa7146_write(dev, RPS 150 saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle);
150 /* turn on rps */ 151 /* turn on rps */
151 saa7146_write(dev, MC1 152 saa7146_write(dev, MC1, (MASK_12 | MASK_28));
152 !! 153
153 /* 154 /*
154 printk("vdma%d.base_ev 155 printk("vdma%d.base_even: 0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1));
155 printk("vdma%d.base_od 156 printk("vdma%d.base_odd: 0x%08x\n", 1,saa7146_read(dev,BASE_ODD1));
156 printk("vdma%d.prot_ad 157 printk("vdma%d.prot_addr: 0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1));
157 printk("vdma%d.base_pa 158 printk("vdma%d.base_page: 0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1));
158 printk("vdma%d.pitch: 159 printk("vdma%d.pitch: 0x%08x\n", 1,saa7146_read(dev,PITCH1));
159 printk("vdma%d.num_lin 160 printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1));
160 */ 161 */
161 } 162 }
162 del_timer(&q->timeout); 163 del_timer(&q->timeout);
163 } 164 }
164 } 165 }
165 166
166 void saa7146_buffer_timeout(unsigned long data 167 void saa7146_buffer_timeout(unsigned long data)
167 { 168 {
168 struct saa7146_dmaqueue *q = (struct s 169 struct saa7146_dmaqueue *q = (struct saa7146_dmaqueue*)data;
169 struct saa7146_dev *dev = q->dev; 170 struct saa7146_dev *dev = q->dev;
170 unsigned long flags; 171 unsigned long flags;
171 172
172 DEB_EE(("dev:%p, dmaq:%p\n", dev, q)); 173 DEB_EE(("dev:%p, dmaq:%p\n", dev, q));
173 174
174 spin_lock_irqsave(&dev->slock,flags); 175 spin_lock_irqsave(&dev->slock,flags);
175 if (q->curr) { 176 if (q->curr) {
176 DEB_D(("timeout on %p\n", q->c 177 DEB_D(("timeout on %p\n", q->curr));
177 saa7146_buffer_finish(dev,q,VI !! 178 saa7146_buffer_finish(dev,q,STATE_ERROR);
178 } 179 }
179 180
180 /* we don't restart the transfer here 181 /* we don't restart the transfer here like other drivers do. when
181 a streaming capture is disabled, th 182 a streaming capture is disabled, the timeout function will be
182 called for the current buffer. if w 183 called for the current buffer. if we activate the next buffer now,
183 we mess up our capture logic. if a 184 we mess up our capture logic. if a timeout occurs on another buffer,
184 then something is seriously broken 185 then something is seriously broken before, so no need to buffer the
185 next capture IMHO... */ 186 next capture IMHO... */
186 /* 187 /*
187 saa7146_buffer_next(dev,q); 188 saa7146_buffer_next(dev,q);
188 */ 189 */
189 spin_unlock_irqrestore(&dev->slock,fla 190 spin_unlock_irqrestore(&dev->slock,flags);
190 } 191 }
191 192
192 /********************************************* 193 /********************************************************************************/
193 /* file operations */ 194 /* file operations */
194 195
195 static int fops_open(struct inode *inode, stru 196 static int fops_open(struct inode *inode, struct file *file)
196 { 197 {
197 unsigned int minor = iminor(inode); 198 unsigned int minor = iminor(inode);
198 struct saa7146_dev *h = NULL, *dev = N 199 struct saa7146_dev *h = NULL, *dev = NULL;
199 struct list_head *list; 200 struct list_head *list;
200 struct saa7146_fh *fh = NULL; 201 struct saa7146_fh *fh = NULL;
201 int result = 0; 202 int result = 0;
202 203
203 enum v4l2_buf_type type = V4L2_BUF_TYP 204 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
204 205
205 DEB_EE(("inode:%p, file:%p, minor:%d\n 206 DEB_EE(("inode:%p, file:%p, minor:%d\n",inode,file,minor));
206 207
207 if (mutex_lock_interruptible(&saa7146_ !! 208 if (down_interruptible(&saa7146_devices_lock))
208 return -ERESTARTSYS; 209 return -ERESTARTSYS;
209 210
210 list_for_each(list,&saa7146_devices) { 211 list_for_each(list,&saa7146_devices) {
211 h = list_entry(list, struct sa 212 h = list_entry(list, struct saa7146_dev, item);
212 if( NULL == h->vv_data ) { 213 if( NULL == h->vv_data ) {
213 DEB_D(("device %p has 214 DEB_D(("device %p has not registered video devices.\n",h));
214 continue; 215 continue;
215 } 216 }
216 DEB_D(("trying: %p @ major %d, 217 DEB_D(("trying: %p @ major %d,%d\n",h,h->vv_data->video_minor,h->vv_data->vbi_minor));
217 218
218 if (h->vv_data->video_minor == 219 if (h->vv_data->video_minor == minor) {
219 dev = h; 220 dev = h;
220 } 221 }
221 if (h->vv_data->vbi_minor == m 222 if (h->vv_data->vbi_minor == minor) {
222 type = V4L2_BUF_TYPE_V 223 type = V4L2_BUF_TYPE_VBI_CAPTURE;
223 dev = h; 224 dev = h;
224 } 225 }
225 } 226 }
226 if (NULL == dev) { 227 if (NULL == dev) {
227 DEB_S(("no such video device.\ 228 DEB_S(("no such video device.\n"));
228 result = -ENODEV; 229 result = -ENODEV;
229 goto out; 230 goto out;
230 } 231 }
231 232
232 DEB_D(("using: %p\n",dev)); 233 DEB_D(("using: %p\n",dev));
233 234
234 /* check if an extension is registered 235 /* check if an extension is registered */
235 if( NULL == dev->ext ) { 236 if( NULL == dev->ext ) {
236 DEB_S(("no extension registere 237 DEB_S(("no extension registered for this device.\n"));
237 result = -ENODEV; 238 result = -ENODEV;
238 goto out; 239 goto out;
239 } 240 }
240 241
241 /* allocate per open data */ 242 /* allocate per open data */
242 fh = kzalloc(sizeof(*fh),GFP_KERNEL); !! 243 fh = kmalloc(sizeof(*fh),GFP_KERNEL);
243 if (NULL == fh) { 244 if (NULL == fh) {
244 DEB_S(("cannot allocate memory 245 DEB_S(("cannot allocate memory for per open data.\n"));
245 result = -ENOMEM; 246 result = -ENOMEM;
246 goto out; 247 goto out;
247 } 248 }
248 !! 249 memset(fh,0,sizeof(*fh));
>> 250
249 file->private_data = fh; 251 file->private_data = fh;
250 fh->dev = dev; 252 fh->dev = dev;
251 fh->type = type; 253 fh->type = type;
252 254
253 if( fh->type == V4L2_BUF_TYPE_VBI_CAPT 255 if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
254 DEB_S(("initializing vbi...\n" 256 DEB_S(("initializing vbi...\n"));
255 if (dev->ext_vv_data->capabili !! 257 result = saa7146_vbi_uops.open(dev,file);
256 result = saa7146_vbi_u <<
257 if (dev->ext_vv_data->vbi_fops <<
258 dev->ext_vv_data->vbi_ <<
259 } else { 258 } else {
260 DEB_S(("initializing video...\ 259 DEB_S(("initializing video...\n"));
261 result = saa7146_video_uops.op 260 result = saa7146_video_uops.open(dev,file);
262 } 261 }
263 262
264 if (0 != result) { 263 if (0 != result) {
265 goto out; 264 goto out;
266 } 265 }
267 266
268 if( 0 == try_module_get(dev->ext->modu 267 if( 0 == try_module_get(dev->ext->module)) {
269 result = -EINVAL; 268 result = -EINVAL;
270 goto out; 269 goto out;
271 } 270 }
272 271
273 result = 0; 272 result = 0;
274 out: 273 out:
275 if (fh && result != 0) { !! 274 if( fh != 0 && result != 0 ) {
276 kfree(fh); 275 kfree(fh);
277 file->private_data = NULL; 276 file->private_data = NULL;
278 } 277 }
279 mutex_unlock(&saa7146_devices_lock); !! 278 up(&saa7146_devices_lock);
280 return result; !! 279 return result;
281 } 280 }
282 281
283 static int fops_release(struct inode *inode, s 282 static int fops_release(struct inode *inode, struct file *file)
284 { 283 {
285 struct saa7146_fh *fh = file->privat 284 struct saa7146_fh *fh = file->private_data;
286 struct saa7146_dev *dev = fh->dev; 285 struct saa7146_dev *dev = fh->dev;
287 286
288 DEB_EE(("inode:%p, file:%p\n",inode,fi 287 DEB_EE(("inode:%p, file:%p\n",inode,file));
289 288
290 if (mutex_lock_interruptible(&saa7146_ !! 289 if (down_interruptible(&saa7146_devices_lock))
291 return -ERESTARTSYS; 290 return -ERESTARTSYS;
292 291
293 if( fh->type == V4L2_BUF_TYPE_VBI_CAPT 292 if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
294 if (dev->ext_vv_data->capabili !! 293 saa7146_vbi_uops.release(dev,file);
295 saa7146_vbi_uops.relea <<
296 if (dev->ext_vv_data->vbi_fops <<
297 dev->ext_vv_data->vbi_ <<
298 } else { 294 } else {
299 saa7146_video_uops.release(dev 295 saa7146_video_uops.release(dev,file);
300 } 296 }
301 297
302 module_put(dev->ext->module); 298 module_put(dev->ext->module);
303 file->private_data = NULL; 299 file->private_data = NULL;
304 kfree(fh); 300 kfree(fh);
305 301
306 mutex_unlock(&saa7146_devices_lock); !! 302 up(&saa7146_devices_lock);
307 303
308 return 0; 304 return 0;
309 } 305 }
310 306
>> 307 int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg);
311 static int fops_ioctl(struct inode *inode, str 308 static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
312 { 309 {
313 /* 310 /*
314 DEB_EE(("inode:%p, file:%p, cmd:%d, ar 311 DEB_EE(("inode:%p, file:%p, cmd:%d, arg:%li\n",inode, file, cmd, arg));
315 */ 312 */
316 return video_usercopy(inode, file, cmd 313 return video_usercopy(inode, file, cmd, arg, saa7146_video_do_ioctl);
317 } 314 }
318 315
319 static int fops_mmap(struct file *file, struct 316 static int fops_mmap(struct file *file, struct vm_area_struct * vma)
320 { 317 {
321 struct saa7146_fh *fh = file->private_ 318 struct saa7146_fh *fh = file->private_data;
322 struct videobuf_queue *q; 319 struct videobuf_queue *q;
323 320
324 switch (fh->type) { 321 switch (fh->type) {
325 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 322 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
326 DEB_EE(("V4L2_BUF_TYPE_VIDEO_C 323 DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, vma:%p\n",file, vma));
327 q = &fh->video_q; 324 q = &fh->video_q;
328 break; 325 break;
329 } 326 }
330 case V4L2_BUF_TYPE_VBI_CAPTURE: { 327 case V4L2_BUF_TYPE_VBI_CAPTURE: {
331 DEB_EE(("V4L2_BUF_TYPE_VBI_CAP 328 DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, vma:%p\n",file, vma));
332 q = &fh->vbi_q; 329 q = &fh->vbi_q;
333 break; 330 break;
334 } 331 }
335 default: 332 default:
336 BUG(); 333 BUG();
337 return 0; 334 return 0;
338 } 335 }
339 <<
340 return videobuf_mmap_mapper(q,vma); 336 return videobuf_mmap_mapper(q,vma);
341 } 337 }
342 338
343 static unsigned int fops_poll(struct file *fil 339 static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
344 { 340 {
345 struct saa7146_fh *fh = file->private_ 341 struct saa7146_fh *fh = file->private_data;
346 struct videobuf_buffer *buf = NULL; 342 struct videobuf_buffer *buf = NULL;
347 struct videobuf_queue *q; 343 struct videobuf_queue *q;
348 344
349 DEB_EE(("file:%p, poll:%p\n",file, wai 345 DEB_EE(("file:%p, poll:%p\n",file, wait));
350 346
351 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->t 347 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
352 if( 0 == fh->vbi_q.streaming ) 348 if( 0 == fh->vbi_q.streaming )
353 return videobuf_poll_s 349 return videobuf_poll_stream(file, &fh->vbi_q, wait);
354 q = &fh->vbi_q; 350 q = &fh->vbi_q;
355 } else { 351 } else {
356 DEB_D(("using video queue.\n") 352 DEB_D(("using video queue.\n"));
357 q = &fh->video_q; 353 q = &fh->video_q;
358 } 354 }
359 355
360 if (!list_empty(&q->stream)) 356 if (!list_empty(&q->stream))
361 buf = list_entry(q->stream.nex 357 buf = list_entry(q->stream.next, struct videobuf_buffer, stream);
362 358
363 if (!buf) { 359 if (!buf) {
364 DEB_D(("buf == NULL!\n")); 360 DEB_D(("buf == NULL!\n"));
365 return POLLERR; 361 return POLLERR;
366 } 362 }
367 363
368 poll_wait(file, &buf->done, wait); 364 poll_wait(file, &buf->done, wait);
369 if (buf->state == VIDEOBUF_DONE || buf !! 365 if (buf->state == STATE_DONE || buf->state == STATE_ERROR) {
370 DEB_D(("poll succeeded!\n")); 366 DEB_D(("poll succeeded!\n"));
371 return POLLIN|POLLRDNORM; 367 return POLLIN|POLLRDNORM;
372 } 368 }
373 369
374 DEB_D(("nothing to poll for, buf->stat 370 DEB_D(("nothing to poll for, buf->state:%d\n",buf->state));
375 return 0; 371 return 0;
376 } 372 }
377 373
378 static ssize_t fops_read(struct file *file, ch 374 static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
379 { 375 {
380 struct saa7146_fh *fh = file->private_ 376 struct saa7146_fh *fh = file->private_data;
381 377
382 switch (fh->type) { 378 switch (fh->type) {
383 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 379 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
384 // DEB_EE(("V4L2_BUF_TYPE_VIDEO_C 380 // DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun", file, data, (unsigned long)count));
385 return saa7146_video_uops.read 381 return saa7146_video_uops.read(file,data,count,ppos);
386 } 382 }
387 case V4L2_BUF_TYPE_VBI_CAPTURE: { 383 case V4L2_BUF_TYPE_VBI_CAPTURE: {
388 // DEB_EE(("V4L2_BUF_TYPE_VBI_CAP 384 // DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count));
389 if (fh->dev->ext_vv_data->capa !! 385 return saa7146_vbi_uops.read(file,data,count,ppos);
390 return saa7146_vbi_uop <<
391 else <<
392 return -EINVAL; <<
393 } 386 }
394 break; 387 break;
395 default: 388 default:
396 BUG(); 389 BUG();
397 return 0; 390 return 0;
398 } 391 }
399 } 392 }
400 393
401 static ssize_t fops_write(struct file *file, c !! 394 static struct file_operations video_fops =
402 { <<
403 struct saa7146_fh *fh = file->private_ <<
404 <<
405 switch (fh->type) { <<
406 case V4L2_BUF_TYPE_VIDEO_CAPTURE: <<
407 return -EINVAL; <<
408 case V4L2_BUF_TYPE_VBI_CAPTURE: <<
409 if (fh->dev->ext_vv_data->vbi_ <<
410 return fh->dev->ext_vv <<
411 else <<
412 return -EINVAL; <<
413 default: <<
414 BUG(); <<
415 return -EINVAL; <<
416 } <<
417 } <<
418 <<
419 static const struct file_operations video_fops <<
420 { 395 {
421 .owner = THIS_MODULE, 396 .owner = THIS_MODULE,
422 .open = fops_open, 397 .open = fops_open,
423 .release = fops_release, 398 .release = fops_release,
424 .read = fops_read, 399 .read = fops_read,
425 .write = fops_write, <<
426 .poll = fops_poll, 400 .poll = fops_poll,
427 .mmap = fops_mmap, 401 .mmap = fops_mmap,
428 .ioctl = fops_ioctl, 402 .ioctl = fops_ioctl,
429 .llseek = no_llseek, 403 .llseek = no_llseek,
430 }; 404 };
431 405
432 static void vv_callback(struct saa7146_dev *de !! 406 void vv_callback(struct saa7146_dev *dev, unsigned long status)
433 { 407 {
434 u32 isr = status; 408 u32 isr = status;
435 !! 409
436 DEB_INT(("dev:%p, isr:0x%08x\n",dev,(u 410 DEB_INT(("dev:%p, isr:0x%08x\n",dev,(u32)status));
437 411
438 if (0 != (isr & (MASK_27))) { 412 if (0 != (isr & (MASK_27))) {
439 DEB_INT(("irq: RPS0 (0x%08x).\ 413 DEB_INT(("irq: RPS0 (0x%08x).\n",isr));
440 saa7146_video_uops.irq_done(de 414 saa7146_video_uops.irq_done(dev,isr);
441 } 415 }
442 416
443 if (0 != (isr & (MASK_28))) { 417 if (0 != (isr & (MASK_28))) {
444 u32 mc2 = saa7146_read(dev, MC 418 u32 mc2 = saa7146_read(dev, MC2);
445 if( 0 != (mc2 & MASK_15)) { 419 if( 0 != (mc2 & MASK_15)) {
446 DEB_INT(("irq: RPS1 vb 420 DEB_INT(("irq: RPS1 vbi workaround (0x%08x).\n",isr));
447 wake_up(&dev->vv_data- 421 wake_up(&dev->vv_data->vbi_wq);
448 saa7146_write(dev,MC2, 422 saa7146_write(dev,MC2, MASK_31);
449 return; 423 return;
450 } 424 }
451 DEB_INT(("irq: RPS1 (0x%08x).\ 425 DEB_INT(("irq: RPS1 (0x%08x).\n",isr));
452 saa7146_vbi_uops.irq_done(dev, 426 saa7146_vbi_uops.irq_done(dev,isr);
453 } 427 }
454 } 428 }
455 429
456 static struct video_device device_template = 430 static struct video_device device_template =
457 { 431 {
>> 432 .hardware = VID_HARDWARE_SAA7146,
458 .fops = &video_fops, 433 .fops = &video_fops,
459 .minor = -1, 434 .minor = -1,
460 }; 435 };
461 436
462 int saa7146_vv_init(struct saa7146_dev* dev, s 437 int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
463 { 438 {
464 struct saa7146_vv *vv = kzalloc (sizeo !! 439 struct saa7146_vv *vv = kmalloc (sizeof(struct saa7146_vv),GFP_KERNEL);
465 if( NULL == vv ) { 440 if( NULL == vv ) {
466 ERR(("out of memory. aborting. 441 ERR(("out of memory. aborting.\n"));
467 return -1; 442 return -1;
468 } 443 }
>> 444 memset(vv, 0x0, sizeof(*vv));
469 445
470 DEB_EE(("dev:%p\n",dev)); 446 DEB_EE(("dev:%p\n",dev));
471 !! 447
472 /* set default values for video parts 448 /* set default values for video parts of the saa7146 */
473 saa7146_write(dev, BCS_CTRL, 0x8040004 449 saa7146_write(dev, BCS_CTRL, 0x80400040);
474 450
475 /* enable video-port pins */ 451 /* enable video-port pins */
476 saa7146_write(dev, MC1, (MASK_10 | MAS 452 saa7146_write(dev, MC1, (MASK_10 | MASK_26));
477 453
478 /* save per-device extension data (one 454 /* save per-device extension data (one extension can
479 handle different devices that might 455 handle different devices that might need different
480 configuration data) */ 456 configuration data) */
481 dev->ext_vv_data = ext_vv; 457 dev->ext_vv_data = ext_vv;
482 !! 458
483 vv->video_minor = -1; 459 vv->video_minor = -1;
484 vv->vbi_minor = -1; 460 vv->vbi_minor = -1;
485 461
486 vv->d_clipping.cpu_addr = pci_alloc_co !! 462 vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle);
487 if( NULL == vv->d_clipping.cpu_addr ) 463 if( NULL == vv->d_clipping.cpu_addr ) {
488 ERR(("out of memory. aborting. 464 ERR(("out of memory. aborting.\n"));
489 kfree(vv); 465 kfree(vv);
490 return -1; 466 return -1;
491 } 467 }
492 memset(vv->d_clipping.cpu_addr, 0x0, S 468 memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM);
493 469
494 saa7146_video_uops.init(dev,vv); 470 saa7146_video_uops.init(dev,vv);
495 if (dev->ext_vv_data->capabilities & V !! 471 saa7146_vbi_uops.init(dev,vv);
496 saa7146_vbi_uops.init(dev,vv); !! 472
497 <<
498 dev->vv_data = vv; 473 dev->vv_data = vv;
499 dev->vv_callback = &vv_callback; 474 dev->vv_callback = &vv_callback;
500 475
501 return 0; 476 return 0;
502 } 477 }
503 EXPORT_SYMBOL_GPL(saa7146_vv_init); <<
504 478
505 int saa7146_vv_release(struct saa7146_dev* dev 479 int saa7146_vv_release(struct saa7146_dev* dev)
506 { 480 {
507 struct saa7146_vv *vv = dev->vv_data; 481 struct saa7146_vv *vv = dev->vv_data;
508 482
509 DEB_EE(("dev:%p\n",dev)); 483 DEB_EE(("dev:%p\n",dev));
510 !! 484
511 pci_free_consistent(dev->pci, SAA7146_ !! 485 pci_free_consistent(dev->pci, SAA7146_RPS_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
512 kfree(vv); !! 486 kfree(vv);
513 dev->vv_data = NULL; 487 dev->vv_data = NULL;
514 dev->vv_callback = NULL; 488 dev->vv_callback = NULL;
515 !! 489
516 return 0; 490 return 0;
517 } 491 }
518 EXPORT_SYMBOL_GPL(saa7146_vv_release); <<
519 492
520 int saa7146_register_device(struct video_devic 493 int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
521 char *name, int ty 494 char *name, int type)
522 { 495 {
523 struct saa7146_vv *vv = dev->vv_data; 496 struct saa7146_vv *vv = dev->vv_data;
524 struct video_device *vfd; 497 struct video_device *vfd;
525 498
526 DEB_EE(("dev:%p, name:'%s', type:%d\n" 499 DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type));
527 !! 500
528 // released by vfd->release 501 // released by vfd->release
529 vfd = video_device_alloc(); !! 502 vfd = video_device_alloc();
530 if (vfd == NULL) 503 if (vfd == NULL)
531 return -ENOMEM; 504 return -ENOMEM;
532 505
533 memcpy(vfd, &device_template, sizeof(s 506 memcpy(vfd, &device_template, sizeof(struct video_device));
534 strlcpy(vfd->name, name, sizeof(vfd->n 507 strlcpy(vfd->name, name, sizeof(vfd->name));
535 vfd->release = video_device_release; 508 vfd->release = video_device_release;
536 vfd->priv = dev; 509 vfd->priv = dev;
537 510
538 // fixme: -1 should be an insmod param 511 // fixme: -1 should be an insmod parameter *for the extension* (like "video_nr");
539 if (video_register_device(vfd, type, - 512 if (video_register_device(vfd, type, -1) < 0) {
540 ERR(("cannot register v4l2 dev 513 ERR(("cannot register v4l2 device. skipping.\n"));
541 video_device_release(vfd); <<
542 return -1; 514 return -1;
543 } 515 }
544 516
545 if( VFL_TYPE_GRABBER == type ) { 517 if( VFL_TYPE_GRABBER == type ) {
546 vv->video_minor = vfd->minor; 518 vv->video_minor = vfd->minor;
547 INFO(("%s: registered device v 519 INFO(("%s: registered device video%d [v4l2]\n",
548 dev->name, vfd->minor 520 dev->name, vfd->minor & 0x1f));
549 } else { 521 } else {
550 vv->vbi_minor = vfd->minor; 522 vv->vbi_minor = vfd->minor;
551 INFO(("%s: registered device v 523 INFO(("%s: registered device vbi%d [v4l2]\n",
552 dev->name, vfd->minor 524 dev->name, vfd->minor & 0x1f));
553 } 525 }
554 526
555 *vid = vfd; 527 *vid = vfd;
556 return 0; 528 return 0;
557 } 529 }
558 EXPORT_SYMBOL_GPL(saa7146_register_device); <<
559 530
560 int saa7146_unregister_device(struct video_dev 531 int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev)
561 { 532 {
562 struct saa7146_vv *vv = dev->vv_data; 533 struct saa7146_vv *vv = dev->vv_data;
563 !! 534
564 DEB_EE(("dev:%p\n",dev)); 535 DEB_EE(("dev:%p\n",dev));
565 536
566 if( VFL_TYPE_GRABBER == (*vid)->type ) 537 if( VFL_TYPE_GRABBER == (*vid)->type ) {
567 vv->video_minor = -1; 538 vv->video_minor = -1;
568 } else { 539 } else {
569 vv->vbi_minor = -1; 540 vv->vbi_minor = -1;
570 } 541 }
571 542
572 video_unregister_device(*vid); 543 video_unregister_device(*vid);
573 *vid = NULL; 544 *vid = NULL;
574 545
575 return 0; 546 return 0;
576 } 547 }
577 EXPORT_SYMBOL_GPL(saa7146_unregister_device); <<
578 548
579 static int __init saa7146_vv_init_module(void) 549 static int __init saa7146_vv_init_module(void)
580 { 550 {
581 return 0; 551 return 0;
582 } 552 }
583 553
584 554
585 static void __exit saa7146_vv_cleanup_module(v 555 static void __exit saa7146_vv_cleanup_module(void)
586 { 556 {
587 } 557 }
588 558
589 module_init(saa7146_vv_init_module); 559 module_init(saa7146_vv_init_module);
590 module_exit(saa7146_vv_cleanup_module); 560 module_exit(saa7146_vv_cleanup_module);
591 561
592 MODULE_AUTHOR("Michael Hunold <michael@mihu.de 562 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
593 MODULE_DESCRIPTION("video4linux driver for saa 563 MODULE_DESCRIPTION("video4linux driver for saa7146-based hardware");
594 MODULE_LICENSE("GPL"); 564 MODULE_LICENSE("GPL");
595 565
|
This page was automatically generated by the
LXR engine.
|