diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2010-03-22 04:13:17 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-17 23:51:30 -0400 |
commit | 271922c0cee0b086ca2fe9cec39d585a44a2358b (patch) | |
tree | cff445792ec52dcdf267a5aaeca7acf9c0eddae2 /drivers/media/video/w9966.c | |
parent | 467422678e9e73bff8d175024cdd89ed48483697 (diff) |
V4L/DVB: w9966: reorganize the order of functions
Get rid of completely unnecessary function prototypes.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/w9966.c')
-rw-r--r-- | drivers/media/video/w9966.c | 563 |
1 files changed, 263 insertions, 300 deletions
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 25364b8f857b..7d5be0700413 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c | |||
@@ -144,77 +144,9 @@ MODULE_PARM_DESC(parmode, "parmode: transfer mode (0=auto, 1=ecp, 2=epp"); | |||
144 | static int video_nr = -1; | 144 | static int video_nr = -1; |
145 | module_param(video_nr, int, 0); | 145 | module_param(video_nr, int, 0); |
146 | 146 | ||
147 | /* | ||
148 | * Private data | ||
149 | */ | ||
150 | |||
151 | static struct w9966_dev w9966_cams[W9966_MAXCAMS]; | 147 | static struct w9966_dev w9966_cams[W9966_MAXCAMS]; |
152 | 148 | ||
153 | /* | 149 | /* |
154 | * Private function declares | ||
155 | */ | ||
156 | |||
157 | static inline void w9966_setState(struct w9966_dev *cam, int mask, int val); | ||
158 | static inline int w9966_getState(struct w9966_dev *cam, int mask, int val); | ||
159 | static inline void w9966_pdev_claim(struct w9966_dev *vdev); | ||
160 | static inline void w9966_pdev_release(struct w9966_dev *vdev); | ||
161 | |||
162 | static int w9966_rReg(struct w9966_dev *cam, int reg); | ||
163 | static int w9966_wReg(struct w9966_dev *cam, int reg, int data); | ||
164 | #if 0 | ||
165 | static int w9966_rReg_i2c(struct w9966_dev *cam, int reg); | ||
166 | #endif | ||
167 | static int w9966_wReg_i2c(struct w9966_dev *cam, int reg, int data); | ||
168 | static int w9966_findlen(int near, int size, int maxlen); | ||
169 | static int w9966_calcscale(int size, int min, int max, int *beg, int *end, unsigned char *factor); | ||
170 | static int w9966_setup(struct w9966_dev *cam, int x1, int y1, int x2, int y2, int w, int h); | ||
171 | |||
172 | static int w9966_init(struct w9966_dev *cam, struct parport* port); | ||
173 | static void w9966_term(struct w9966_dev *cam); | ||
174 | |||
175 | static inline void w9966_i2c_setsda(struct w9966_dev *cam, int state); | ||
176 | static inline int w9966_i2c_setscl(struct w9966_dev *cam, int state); | ||
177 | static inline int w9966_i2c_getsda(struct w9966_dev *cam); | ||
178 | static inline int w9966_i2c_getscl(struct w9966_dev *cam); | ||
179 | static int w9966_i2c_wbyte(struct w9966_dev *cam, int data); | ||
180 | #if 0 | ||
181 | static int w9966_i2c_rbyte(struct w9966_dev *cam); | ||
182 | #endif | ||
183 | |||
184 | static long w9966_v4l_ioctl(struct file *file, | ||
185 | unsigned int cmd, unsigned long arg); | ||
186 | static ssize_t w9966_v4l_read(struct file *file, char __user *buf, | ||
187 | size_t count, loff_t *ppos); | ||
188 | |||
189 | static int w9966_exclusive_open(struct file *file) | ||
190 | { | ||
191 | struct w9966_dev *cam = video_drvdata(file); | ||
192 | |||
193 | return test_and_set_bit(0, &cam->in_use) ? -EBUSY : 0; | ||
194 | } | ||
195 | |||
196 | static int w9966_exclusive_release(struct file *file) | ||
197 | { | ||
198 | struct w9966_dev *cam = video_drvdata(file); | ||
199 | |||
200 | clear_bit(0, &cam->in_use); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static const struct v4l2_file_operations w9966_fops = { | ||
205 | .owner = THIS_MODULE, | ||
206 | .open = w9966_exclusive_open, | ||
207 | .release = w9966_exclusive_release, | ||
208 | .ioctl = w9966_v4l_ioctl, | ||
209 | .read = w9966_v4l_read, | ||
210 | }; | ||
211 | static struct video_device w9966_template = { | ||
212 | .name = W9966_DRIVERNAME, | ||
213 | .fops = &w9966_fops, | ||
214 | .release = video_device_release_empty, | ||
215 | }; | ||
216 | |||
217 | /* | ||
218 | * Private function defines | 150 | * Private function defines |
219 | */ | 151 | */ |
220 | 152 | ||
@@ -232,7 +164,7 @@ static inline int w9966_getState(struct w9966_dev *cam, int mask, int val) | |||
232 | } | 164 | } |
233 | 165 | ||
234 | /* Claim parport for ourself */ | 166 | /* Claim parport for ourself */ |
235 | static inline void w9966_pdev_claim(struct w9966_dev *cam) | 167 | static void w9966_pdev_claim(struct w9966_dev *cam) |
236 | { | 168 | { |
237 | if (w9966_getState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED)) | 169 | if (w9966_getState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED)) |
238 | return; | 170 | return; |
@@ -241,7 +173,7 @@ static inline void w9966_pdev_claim(struct w9966_dev *cam) | |||
241 | } | 173 | } |
242 | 174 | ||
243 | /* Release parport for others to use */ | 175 | /* Release parport for others to use */ |
244 | static inline void w9966_pdev_release(struct w9966_dev *cam) | 176 | static void w9966_pdev_release(struct w9966_dev *cam) |
245 | { | 177 | { |
246 | if (w9966_getState(cam, W9966_STATE_CLAIMED, 0)) | 178 | if (w9966_getState(cam, W9966_STATE_CLAIMED, 0)) |
247 | return; | 179 | return; |
@@ -291,97 +223,168 @@ static int w9966_wReg(struct w9966_dev *cam, int reg, int data) | |||
291 | return 0; | 223 | return 0; |
292 | } | 224 | } |
293 | 225 | ||
294 | /* Initialize camera device. Setup all internal flags, set a | 226 | /* |
295 | default video mode, setup ccd-chip, register v4l device etc.. | 227 | * Ugly and primitive i2c protocol functions |
296 | Also used for 'probing' of hardware. | 228 | */ |
297 | -1 on error */ | 229 | |
298 | static int w9966_init(struct w9966_dev *cam, struct parport* port) | 230 | /* Sets the data line on the i2c bus. |
231 | Expects a claimed pdev. */ | ||
232 | static void w9966_i2c_setsda(struct w9966_dev *cam, int state) | ||
299 | { | 233 | { |
300 | if (cam->dev_state != 0) | 234 | if (state) |
301 | return -1; | 235 | cam->i2c_state |= W9966_I2C_W_DATA; |
236 | else | ||
237 | cam->i2c_state &= ~W9966_I2C_W_DATA; | ||
302 | 238 | ||
303 | cam->pport = port; | 239 | w9966_wReg(cam, 0x18, cam->i2c_state); |
304 | cam->brightness = 128; | 240 | udelay(5); |
305 | cam->contrast = 64; | 241 | } |
306 | cam->color = 64; | ||
307 | cam->hue = 0; | ||
308 | 242 | ||
309 | /* Select requested transfer mode */ | 243 | /* Get peripheral clock line |
310 | switch (parmode) { | 244 | Expects a claimed pdev. */ |
311 | default: /* Auto-detect (priority: hw-ecp, hw-epp, sw-ecp) */ | 245 | static int w9966_i2c_getscl(struct w9966_dev *cam) |
312 | case 0: | 246 | { |
313 | if (port->modes & PARPORT_MODE_ECP) | 247 | const unsigned char state = w9966_rReg(cam, 0x18); |
314 | cam->ppmode = IEEE1284_MODE_ECP; | 248 | return ((state & W9966_I2C_R_CLOCK) > 0); |
315 | else if (port->modes & PARPORT_MODE_EPP) | 249 | } |
316 | cam->ppmode = IEEE1284_MODE_EPP; | 250 | |
317 | else | 251 | /* Sets the clock line on the i2c bus. |
318 | cam->ppmode = IEEE1284_MODE_ECP; | 252 | Expects a claimed pdev. -1 on error */ |
319 | break; | 253 | static int w9966_i2c_setscl(struct w9966_dev *cam, int state) |
320 | case 1: /* hw- or sw-ecp */ | 254 | { |
321 | cam->ppmode = IEEE1284_MODE_ECP; | 255 | unsigned long timeout; |
322 | break; | 256 | |
323 | case 2: /* hw- or sw-epp */ | 257 | if (state) |
324 | cam->ppmode = IEEE1284_MODE_EPP; | 258 | cam->i2c_state |= W9966_I2C_W_CLOCK; |
325 | break; | 259 | else |
260 | cam->i2c_state &= ~W9966_I2C_W_CLOCK; | ||
261 | |||
262 | w9966_wReg(cam, 0x18, cam->i2c_state); | ||
263 | udelay(5); | ||
264 | |||
265 | /* we go to high, we also expect the peripheral to ack. */ | ||
266 | if (state) { | ||
267 | timeout = jiffies + 100; | ||
268 | while (!w9966_i2c_getscl(cam)) { | ||
269 | if (time_after(jiffies, timeout)) | ||
270 | return -1; | ||
271 | } | ||
326 | } | 272 | } |
273 | return 0; | ||
274 | } | ||
327 | 275 | ||
328 | /* Tell the parport driver that we exists */ | 276 | #if 0 |
329 | cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL); | 277 | /* Get peripheral data line |
330 | if (cam->pdev == NULL) { | 278 | Expects a claimed pdev. */ |
331 | DPRINTF("parport_register_device() failed\n"); | 279 | static int w9966_i2c_getsda(struct w9966_dev *cam) |
332 | return -1; | 280 | { |
281 | const unsigned char state = w9966_rReg(cam, 0x18); | ||
282 | return ((state & W9966_I2C_R_DATA) > 0); | ||
283 | } | ||
284 | #endif | ||
285 | |||
286 | /* Write a byte with ack to the i2c bus. | ||
287 | Expects a claimed pdev. -1 on error */ | ||
288 | static int w9966_i2c_wbyte(struct w9966_dev *cam, int data) | ||
289 | { | ||
290 | int i; | ||
291 | |||
292 | for (i = 7; i >= 0; i--) { | ||
293 | w9966_i2c_setsda(cam, (data >> i) & 0x01); | ||
294 | |||
295 | if (w9966_i2c_setscl(cam, 1) == -1) | ||
296 | return -1; | ||
297 | w9966_i2c_setscl(cam, 0); | ||
333 | } | 298 | } |
334 | w9966_setState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV); | ||
335 | 299 | ||
336 | w9966_pdev_claim(cam); | 300 | w9966_i2c_setsda(cam, 1); |
337 | 301 | ||
338 | /* Setup a default capture mode */ | 302 | if (w9966_i2c_setscl(cam, 1) == -1) |
339 | if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) { | ||
340 | DPRINTF("w9966_setup() failed.\n"); | ||
341 | return -1; | 303 | return -1; |
304 | w9966_i2c_setscl(cam, 0); | ||
305 | |||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | /* Read a data byte with ack from the i2c-bus | ||
310 | Expects a claimed pdev. -1 on error */ | ||
311 | #if 0 | ||
312 | static int w9966_i2c_rbyte(struct w9966_dev *cam) | ||
313 | { | ||
314 | unsigned char data = 0x00; | ||
315 | int i; | ||
316 | |||
317 | w9966_i2c_setsda(cam, 1); | ||
318 | |||
319 | for (i = 0; i < 8; i++) { | ||
320 | if (w9966_i2c_setscl(cam, 1) == -1) | ||
321 | return -1; | ||
322 | data = data << 1; | ||
323 | if (w9966_i2c_getsda(cam)) | ||
324 | data |= 0x01; | ||
325 | |||
326 | w9966_i2c_setscl(cam, 0); | ||
342 | } | 327 | } |
328 | return data; | ||
329 | } | ||
330 | #endif | ||
343 | 331 | ||
344 | w9966_pdev_release(cam); | 332 | /* Read a register from the i2c device. |
333 | Expects claimed pdev. -1 on error */ | ||
334 | #if 0 | ||
335 | static int w9966_rReg_i2c(struct w9966_dev *cam, int reg) | ||
336 | { | ||
337 | int data; | ||
345 | 338 | ||
346 | /* Fill in the video_device struct and register us to v4l */ | 339 | w9966_i2c_setsda(cam, 0); |
347 | memcpy(&cam->vdev, &w9966_template, sizeof(struct video_device)); | 340 | w9966_i2c_setscl(cam, 0); |
348 | video_set_drvdata(&cam->vdev, cam); | ||
349 | 341 | ||
350 | if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) | 342 | if (w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 || |
343 | w9966_i2c_wbyte(cam, reg) == -1) | ||
351 | return -1; | 344 | return -1; |
352 | 345 | ||
353 | w9966_setState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV); | 346 | w9966_i2c_setsda(cam, 1); |
347 | if (w9966_i2c_setscl(cam, 1) == -1) | ||
348 | return -1; | ||
349 | w9966_i2c_setsda(cam, 0); | ||
350 | w9966_i2c_setscl(cam, 0); | ||
354 | 351 | ||
355 | /* All ok */ | 352 | if (w9966_i2c_wbyte(cam, W9966_I2C_R_ID) == -1) |
356 | printk(KERN_INFO "w9966cf: Found and initialized a webcam on %s.\n", | 353 | return -1; |
357 | cam->pport->name); | 354 | data = w9966_i2c_rbyte(cam); |
358 | return 0; | 355 | if (data == -1) |
359 | } | 356 | return -1; |
360 | 357 | ||
358 | w9966_i2c_setsda(cam, 0); | ||
361 | 359 | ||
362 | /* Terminate everything gracefully */ | 360 | if (w9966_i2c_setscl(cam, 1) == -1) |
363 | static void w9966_term(struct w9966_dev *cam) | 361 | return -1; |
362 | w9966_i2c_setsda(cam, 1); | ||
363 | |||
364 | return data; | ||
365 | } | ||
366 | #endif | ||
367 | |||
368 | /* Write a register to the i2c device. | ||
369 | Expects claimed pdev. -1 on error */ | ||
370 | static int w9966_wReg_i2c(struct w9966_dev *cam, int reg, int data) | ||
364 | { | 371 | { |
365 | /* Unregister from v4l */ | 372 | w9966_i2c_setsda(cam, 0); |
366 | if (w9966_getState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) { | 373 | w9966_i2c_setscl(cam, 0); |
367 | video_unregister_device(&cam->vdev); | ||
368 | w9966_setState(cam, W9966_STATE_VDEV, 0); | ||
369 | } | ||
370 | 374 | ||
371 | /* Terminate from IEEE1284 mode and release pdev block */ | 375 | if (w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 || |
372 | if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) { | 376 | w9966_i2c_wbyte(cam, reg) == -1 || |
373 | w9966_pdev_claim(cam); | 377 | w9966_i2c_wbyte(cam, data) == -1) |
374 | parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT); | 378 | return -1; |
375 | w9966_pdev_release(cam); | ||
376 | } | ||
377 | 379 | ||
378 | /* Unregister from parport */ | 380 | w9966_i2c_setsda(cam, 0); |
379 | if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) { | 381 | if (w9966_i2c_setscl(cam, 1) == -1) |
380 | parport_unregister_device(cam->pdev); | 382 | return -1; |
381 | w9966_setState(cam, W9966_STATE_PDEV, 0); | ||
382 | } | ||
383 | } | ||
384 | 383 | ||
384 | w9966_i2c_setsda(cam, 1); | ||
385 | |||
386 | return 0; | ||
387 | } | ||
385 | 388 | ||
386 | /* Find a good length for capture window (used both for W and H) | 389 | /* Find a good length for capture window (used both for W and H) |
387 | A bit ugly but pretty functional. The capture length | 390 | A bit ugly but pretty functional. The capture length |
@@ -551,167 +554,6 @@ static int w9966_setup(struct w9966_dev *cam, int x1, int y1, int x2, int y2, in | |||
551 | } | 554 | } |
552 | 555 | ||
553 | /* | 556 | /* |
554 | * Ugly and primitive i2c protocol functions | ||
555 | */ | ||
556 | |||
557 | /* Sets the data line on the i2c bus. | ||
558 | Expects a claimed pdev. */ | ||
559 | static inline void w9966_i2c_setsda(struct w9966_dev *cam, int state) | ||
560 | { | ||
561 | if (state) | ||
562 | cam->i2c_state |= W9966_I2C_W_DATA; | ||
563 | else | ||
564 | cam->i2c_state &= ~W9966_I2C_W_DATA; | ||
565 | |||
566 | w9966_wReg(cam, 0x18, cam->i2c_state); | ||
567 | udelay(5); | ||
568 | } | ||
569 | |||
570 | /* Get peripheral clock line | ||
571 | Expects a claimed pdev. */ | ||
572 | static inline int w9966_i2c_getscl(struct w9966_dev *cam) | ||
573 | { | ||
574 | const unsigned char state = w9966_rReg(cam, 0x18); | ||
575 | return ((state & W9966_I2C_R_CLOCK) > 0); | ||
576 | } | ||
577 | |||
578 | /* Sets the clock line on the i2c bus. | ||
579 | Expects a claimed pdev. -1 on error */ | ||
580 | static inline int w9966_i2c_setscl(struct w9966_dev *cam, int state) | ||
581 | { | ||
582 | unsigned long timeout; | ||
583 | |||
584 | if (state) | ||
585 | cam->i2c_state |= W9966_I2C_W_CLOCK; | ||
586 | else | ||
587 | cam->i2c_state &= ~W9966_I2C_W_CLOCK; | ||
588 | |||
589 | w9966_wReg(cam, 0x18, cam->i2c_state); | ||
590 | udelay(5); | ||
591 | |||
592 | /* we go to high, we also expect the peripheral to ack. */ | ||
593 | if (state) { | ||
594 | timeout = jiffies + 100; | ||
595 | while (!w9966_i2c_getscl(cam)) { | ||
596 | if (time_after(jiffies, timeout)) | ||
597 | return -1; | ||
598 | } | ||
599 | } | ||
600 | return 0; | ||
601 | } | ||
602 | |||
603 | /* Get peripheral data line | ||
604 | Expects a claimed pdev. */ | ||
605 | static inline int w9966_i2c_getsda(struct w9966_dev *cam) | ||
606 | { | ||
607 | const unsigned char state = w9966_rReg(cam, 0x18); | ||
608 | return ((state & W9966_I2C_R_DATA) > 0); | ||
609 | } | ||
610 | |||
611 | /* Write a byte with ack to the i2c bus. | ||
612 | Expects a claimed pdev. -1 on error */ | ||
613 | static int w9966_i2c_wbyte(struct w9966_dev *cam, int data) | ||
614 | { | ||
615 | int i; | ||
616 | |||
617 | for (i = 7; i >= 0; i--) { | ||
618 | w9966_i2c_setsda(cam, (data >> i) & 0x01); | ||
619 | |||
620 | if (w9966_i2c_setscl(cam, 1) == -1) | ||
621 | return -1; | ||
622 | w9966_i2c_setscl(cam, 0); | ||
623 | } | ||
624 | |||
625 | w9966_i2c_setsda(cam, 1); | ||
626 | |||
627 | if (w9966_i2c_setscl(cam, 1) == -1) | ||
628 | return -1; | ||
629 | w9966_i2c_setscl(cam, 0); | ||
630 | |||
631 | return 0; | ||
632 | } | ||
633 | |||
634 | /* Read a data byte with ack from the i2c-bus | ||
635 | Expects a claimed pdev. -1 on error */ | ||
636 | #if 0 | ||
637 | static int w9966_i2c_rbyte(struct w9966_dev *cam) | ||
638 | { | ||
639 | unsigned char data = 0x00; | ||
640 | int i; | ||
641 | |||
642 | w9966_i2c_setsda(cam, 1); | ||
643 | |||
644 | for (i = 0; i < 8; i++) { | ||
645 | if (w9966_i2c_setscl(cam, 1) == -1) | ||
646 | return -1; | ||
647 | data = data << 1; | ||
648 | if (w9966_i2c_getsda(cam)) | ||
649 | data |= 0x01; | ||
650 | |||
651 | w9966_i2c_setscl(cam, 0); | ||
652 | } | ||
653 | return data; | ||
654 | } | ||
655 | #endif | ||
656 | |||
657 | /* Read a register from the i2c device. | ||
658 | Expects claimed pdev. -1 on error */ | ||
659 | #if 0 | ||
660 | static int w9966_rReg_i2c(struct w9966_dev *cam, int reg) | ||
661 | { | ||
662 | int data; | ||
663 | |||
664 | w9966_i2c_setsda(cam, 0); | ||
665 | w9966_i2c_setscl(cam, 0); | ||
666 | |||
667 | if (w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 || | ||
668 | w9966_i2c_wbyte(cam, reg) == -1) | ||
669 | return -1; | ||
670 | |||
671 | w9966_i2c_setsda(cam, 1); | ||
672 | if (w9966_i2c_setscl(cam, 1) == -1) | ||
673 | return -1; | ||
674 | w9966_i2c_setsda(cam, 0); | ||
675 | w9966_i2c_setscl(cam, 0); | ||
676 | |||
677 | if (w9966_i2c_wbyte(cam, W9966_I2C_R_ID) == -1) | ||
678 | return -1; | ||
679 | data = w9966_i2c_rbyte(cam); | ||
680 | if (data == -1) | ||
681 | return -1; | ||
682 | |||
683 | w9966_i2c_setsda(cam, 0); | ||
684 | |||
685 | if (w9966_i2c_setscl(cam, 1) == -1) | ||
686 | return -1; | ||
687 | w9966_i2c_setsda(cam, 1); | ||
688 | |||
689 | return data; | ||
690 | } | ||
691 | #endif | ||
692 | |||
693 | /* Write a register to the i2c device. | ||
694 | Expects claimed pdev. -1 on error */ | ||
695 | static int w9966_wReg_i2c(struct w9966_dev *cam, int reg, int data) | ||
696 | { | ||
697 | w9966_i2c_setsda(cam, 0); | ||
698 | w9966_i2c_setscl(cam, 0); | ||
699 | |||
700 | if (w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 || | ||
701 | w9966_i2c_wbyte(cam, reg) == -1 || | ||
702 | w9966_i2c_wbyte(cam, data) == -1) | ||
703 | return -1; | ||
704 | |||
705 | w9966_i2c_setsda(cam, 0); | ||
706 | if (w9966_i2c_setscl(cam, 1) == -1) | ||
707 | return -1; | ||
708 | |||
709 | w9966_i2c_setsda(cam, 1); | ||
710 | |||
711 | return 0; | ||
712 | } | ||
713 | |||
714 | /* | ||
715 | * Video4linux interfacing | 557 | * Video4linux interfacing |
716 | */ | 558 | */ |
717 | 559 | ||
@@ -927,6 +769,127 @@ out: | |||
927 | return count; | 769 | return count; |
928 | } | 770 | } |
929 | 771 | ||
772 | static int w9966_exclusive_open(struct file *file) | ||
773 | { | ||
774 | struct w9966_dev *cam = video_drvdata(file); | ||
775 | |||
776 | return test_and_set_bit(0, &cam->in_use) ? -EBUSY : 0; | ||
777 | } | ||
778 | |||
779 | static int w9966_exclusive_release(struct file *file) | ||
780 | { | ||
781 | struct w9966_dev *cam = video_drvdata(file); | ||
782 | |||
783 | clear_bit(0, &cam->in_use); | ||
784 | return 0; | ||
785 | } | ||
786 | |||
787 | static const struct v4l2_file_operations w9966_fops = { | ||
788 | .owner = THIS_MODULE, | ||
789 | .open = w9966_exclusive_open, | ||
790 | .release = w9966_exclusive_release, | ||
791 | .ioctl = w9966_v4l_ioctl, | ||
792 | .read = w9966_v4l_read, | ||
793 | }; | ||
794 | |||
795 | static struct video_device w9966_template = { | ||
796 | .name = W9966_DRIVERNAME, | ||
797 | .fops = &w9966_fops, | ||
798 | .release = video_device_release_empty, | ||
799 | }; | ||
800 | |||
801 | |||
802 | /* Initialize camera device. Setup all internal flags, set a | ||
803 | default video mode, setup ccd-chip, register v4l device etc.. | ||
804 | Also used for 'probing' of hardware. | ||
805 | -1 on error */ | ||
806 | static int w9966_init(struct w9966_dev *cam, struct parport* port) | ||
807 | { | ||
808 | if (cam->dev_state != 0) | ||
809 | return -1; | ||
810 | |||
811 | cam->pport = port; | ||
812 | cam->brightness = 128; | ||
813 | cam->contrast = 64; | ||
814 | cam->color = 64; | ||
815 | cam->hue = 0; | ||
816 | |||
817 | /* Select requested transfer mode */ | ||
818 | switch (parmode) { | ||
819 | default: /* Auto-detect (priority: hw-ecp, hw-epp, sw-ecp) */ | ||
820 | case 0: | ||
821 | if (port->modes & PARPORT_MODE_ECP) | ||
822 | cam->ppmode = IEEE1284_MODE_ECP; | ||
823 | else if (port->modes & PARPORT_MODE_EPP) | ||
824 | cam->ppmode = IEEE1284_MODE_EPP; | ||
825 | else | ||
826 | cam->ppmode = IEEE1284_MODE_ECP; | ||
827 | break; | ||
828 | case 1: /* hw- or sw-ecp */ | ||
829 | cam->ppmode = IEEE1284_MODE_ECP; | ||
830 | break; | ||
831 | case 2: /* hw- or sw-epp */ | ||
832 | cam->ppmode = IEEE1284_MODE_EPP; | ||
833 | break; | ||
834 | } | ||
835 | |||
836 | /* Tell the parport driver that we exists */ | ||
837 | cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL); | ||
838 | if (cam->pdev == NULL) { | ||
839 | DPRINTF("parport_register_device() failed\n"); | ||
840 | return -1; | ||
841 | } | ||
842 | w9966_setState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV); | ||
843 | |||
844 | w9966_pdev_claim(cam); | ||
845 | |||
846 | /* Setup a default capture mode */ | ||
847 | if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) { | ||
848 | DPRINTF("w9966_setup() failed.\n"); | ||
849 | return -1; | ||
850 | } | ||
851 | |||
852 | w9966_pdev_release(cam); | ||
853 | |||
854 | /* Fill in the video_device struct and register us to v4l */ | ||
855 | memcpy(&cam->vdev, &w9966_template, sizeof(struct video_device)); | ||
856 | video_set_drvdata(&cam->vdev, cam); | ||
857 | |||
858 | if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) | ||
859 | return -1; | ||
860 | |||
861 | w9966_setState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV); | ||
862 | |||
863 | /* All ok */ | ||
864 | printk(KERN_INFO "w9966cf: Found and initialized a webcam on %s.\n", | ||
865 | cam->pport->name); | ||
866 | return 0; | ||
867 | } | ||
868 | |||
869 | |||
870 | /* Terminate everything gracefully */ | ||
871 | static void w9966_term(struct w9966_dev *cam) | ||
872 | { | ||
873 | /* Unregister from v4l */ | ||
874 | if (w9966_getState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) { | ||
875 | video_unregister_device(&cam->vdev); | ||
876 | w9966_setState(cam, W9966_STATE_VDEV, 0); | ||
877 | } | ||
878 | |||
879 | /* Terminate from IEEE1284 mode and release pdev block */ | ||
880 | if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) { | ||
881 | w9966_pdev_claim(cam); | ||
882 | parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT); | ||
883 | w9966_pdev_release(cam); | ||
884 | } | ||
885 | |||
886 | /* Unregister from parport */ | ||
887 | if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) { | ||
888 | parport_unregister_device(cam->pdev); | ||
889 | w9966_setState(cam, W9966_STATE_PDEV, 0); | ||
890 | } | ||
891 | } | ||
892 | |||
930 | 893 | ||
931 | /* Called once for every parport on init */ | 894 | /* Called once for every parport on init */ |
932 | static void w9966_attach(struct parport *port) | 895 | static void w9966_attach(struct parport *port) |