/* Claim parport for ourself */ static void w9966_pdev_claim(struct w9966 *cam) { if (w9966_get_state(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED)) return; parport_claim_or_block(cam->pdev); w9966_set_state(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED); }
/* Release parport for others to use */ static void w9966_pdev_release(struct w9966 *cam) { if (w9966_get_state(cam, W9966_STATE_CLAIMED, 0)) return; parport_release(cam->pdev); w9966_set_state(cam, W9966_STATE_CLAIMED, 0); }
/* Terminate everything gracefully */ static void w9966_term(struct w9966 *cam) { /* Unregister from v4l */ if (w9966_get_state(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) { video_unregister_device(&cam->vdev); w9966_set_state(cam, W9966_STATE_VDEV, 0); } /* Terminate from IEEE1284 mode and release pdev block */ if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) { w9966_pdev_claim(cam); parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT); w9966_pdev_release(cam); } /* Unregister from parport */ if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) { parport_unregister_device(cam->pdev); w9966_set_state(cam, W9966_STATE_PDEV, 0); } }
/* Initialize camera device. Setup all internal flags, set a default video mode, setup ccd-chip, register v4l device etc.. Also used for 'probing' of hardware. -1 on error */ static int w9966_init(struct w9966 *cam, struct parport *port) { struct v4l2_device *v4l2_dev = &cam->v4l2_dev; if (cam->dev_state != 0) return -1; strlcpy(v4l2_dev->name, "w9966", sizeof(v4l2_dev->name)); if (v4l2_device_register(NULL, v4l2_dev) < 0) { v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); return -1; } cam->pport = port; cam->brightness = 128; cam->contrast = 64; cam->color = 64; cam->hue = 0; /* Select requested transfer mode */ switch (parmode) { default: /* Auto-detect (priority: hw-ecp, hw-epp, sw-ecp) */ case 0: if (port->modes & PARPORT_MODE_ECP) cam->ppmode = IEEE1284_MODE_ECP; else if (port->modes & PARPORT_MODE_EPP) cam->ppmode = IEEE1284_MODE_EPP; else cam->ppmode = IEEE1284_MODE_ECP; break; case 1: /* hw- or sw-ecp */ cam->ppmode = IEEE1284_MODE_ECP; break; case 2: /* hw- or sw-epp */ cam->ppmode = IEEE1284_MODE_EPP; break; } /* Tell the parport driver that we exists */ cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL); if (cam->pdev == NULL) { DPRINTF("parport_register_device() failed\n"); return -1; } w9966_set_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV); w9966_pdev_claim(cam); /* Setup a default capture mode */ if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) { DPRINTF("w9966_setup() failed.\n"); return -1; } w9966_pdev_release(cam); /* Fill in the video_device struct and register us to v4l */ strlcpy(cam->vdev.name, W9966_DRIVERNAME, sizeof(cam->vdev.name)); cam->vdev.v4l2_dev = v4l2_dev; cam->vdev.fops = &w9966_fops; cam->vdev.ioctl_ops = &w9966_ioctl_ops; cam->vdev.release = video_device_release_empty; video_set_drvdata(&cam->vdev, cam); mutex_init(&cam->lock); if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) return -1; w9966_set_state(cam, W9966_STATE_VDEV, W9966_STATE_VDEV); /* All ok */ v4l2_info(v4l2_dev, "Found and initialized a webcam on %s.\n", cam->pport->name); return 0; }