soc_camera.c 32.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * camera image capture (abstract) bus driver
 *
 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
 *
 * This driver provides an interface between platform-specific camera
 * busses and camera devices. It should be used if the camera is
 * connected not over a "proper" bus like PCI or USB, but over a
 * special bus, like, for example, the Quick Capture interface on PXA270
 * SoCs. Later it should also be used for i.MX31 SoCs from Freescale.
 * It can handle multiple cameras and / or multiple busses, which can
 * be used, e.g., in stereo-vision applications.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/device.h>
#include <linux/err.h>
21 22 23
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/list.h>
24
#include <linux/mutex.h>
25
#include <linux/module.h>
26
#include <linux/platform_device.h>
27 28
#include <linux/vmalloc.h>

29
#include <media/soc_camera.h>
30
#include <media/v4l2-common.h>
31
#include <media/v4l2-ioctl.h>
32
#include <media/v4l2-dev.h>
33
#include <media/videobuf-core.h>
34

35 36 37 38
/* Default to VGA resolution */
#define DEFAULT_WIDTH	640
#define DEFAULT_HEIGHT	480

39 40
static LIST_HEAD(hosts);
static LIST_HEAD(devices);
41
static DEFINE_MUTEX(list_lock);		/* Protects the list of hosts */
42

43
const struct soc_camera_data_format *soc_camera_format_by_fourcc(
44
	struct soc_camera_device *icd, unsigned int fourcc)
45 46 47
{
	unsigned int i;

48 49 50
	for (i = 0; i < icd->num_formats; i++)
		if (icd->formats[i].fourcc == fourcc)
			return icd->formats + i;
51 52
	return NULL;
}
53
EXPORT_SYMBOL(soc_camera_format_by_fourcc);
54

55 56 57 58 59 60 61 62 63 64 65 66
const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
	struct soc_camera_device *icd, unsigned int fourcc)
{
	unsigned int i;

	for (i = 0; i < icd->num_user_formats; i++)
		if (icd->user_formats[i].host_fmt->fourcc == fourcc)
			return icd->user_formats + i;
	return NULL;
}
EXPORT_SYMBOL(soc_camera_xlate_by_fourcc);

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
/**
 * soc_camera_apply_sensor_flags() - apply platform SOCAM_SENSOR_INVERT_* flags
 * @icl:	camera platform parameters
 * @flags:	flags to be inverted according to platform configuration
 * @return:	resulting flags
 */
unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
					    unsigned long flags)
{
	unsigned long f;

	/* If only one of the two polarities is supported, switch to the opposite */
	if (icl->flags & SOCAM_SENSOR_INVERT_HSYNC) {
		f = flags & (SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW);
		if (f == SOCAM_HSYNC_ACTIVE_HIGH || f == SOCAM_HSYNC_ACTIVE_LOW)
			flags ^= SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW;
	}

	if (icl->flags & SOCAM_SENSOR_INVERT_VSYNC) {
		f = flags & (SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW);
		if (f == SOCAM_VSYNC_ACTIVE_HIGH || f == SOCAM_VSYNC_ACTIVE_LOW)
			flags ^= SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW;
	}

	if (icl->flags & SOCAM_SENSOR_INVERT_PCLK) {
		f = flags & (SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING);
		if (f == SOCAM_PCLK_SAMPLE_RISING || f == SOCAM_PCLK_SAMPLE_FALLING)
			flags ^= SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING;
	}

	return flags;
}
EXPORT_SYMBOL(soc_camera_apply_sensor_flags);

101
static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
102
				      struct v4l2_format *f)
103 104 105
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
106
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
107 108 109

	WARN_ON(priv != file->private_data);

110
	/* limit format to hardware capabilities */
111
	return ici->ops->try_fmt(icd, f);
112 113 114 115 116
}

static int soc_camera_enum_input(struct file *file, void *priv,
				 struct v4l2_input *inp)
{
117 118 119 120
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
	int ret = 0;

121 122 123
	if (inp->index != 0)
		return -EINVAL;

124 125 126 127 128 129 130 131
	if (icd->ops->enum_input)
		ret = icd->ops->enum_input(icd, inp);
	else {
		/* default is camera */
		inp->type = V4L2_INPUT_TYPE_CAMERA;
		inp->std  = V4L2_STD_UNKNOWN;
		strcpy(inp->name, "Camera");
	}
132

133
	return ret;
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
}

static int soc_camera_g_input(struct file *file, void *priv, unsigned int *i)
{
	*i = 0;

	return 0;
}

static int soc_camera_s_input(struct file *file, void *priv, unsigned int i)
{
	if (i > 0)
		return -EINVAL;

	return 0;
}

static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
{
153 154 155 156 157 158 159 160
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
	int ret = 0;

	if (icd->ops->set_std)
		ret = icd->ops->set_std(icd, a);

	return ret;
161 162 163 164 165 166 167 168
}

static int soc_camera_reqbufs(struct file *file, void *priv,
			      struct v4l2_requestbuffers *p)
{
	int ret;
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
169
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
170 171 172 173 174 175 176

	WARN_ON(priv != file->private_data);

	ret = videobuf_reqbufs(&icf->vb_vidq, p);
	if (ret < 0)
		return ret;

177
	return ici->ops->reqbufs(icf, p);
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
}

static int soc_camera_querybuf(struct file *file, void *priv,
			       struct v4l2_buffer *p)
{
	struct soc_camera_file *icf = file->private_data;

	WARN_ON(priv != file->private_data);

	return videobuf_querybuf(&icf->vb_vidq, p);
}

static int soc_camera_qbuf(struct file *file, void *priv,
			   struct v4l2_buffer *p)
{
	struct soc_camera_file *icf = file->private_data;

	WARN_ON(priv != file->private_data);

	return videobuf_qbuf(&icf->vb_vidq, p);
}

static int soc_camera_dqbuf(struct file *file, void *priv,
			    struct v4l2_buffer *p)
{
	struct soc_camera_file *icf = file->private_data;

	WARN_ON(priv != file->private_data);

	return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK);
}

210
/* Always entered with .video_lock held */
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
static int soc_camera_init_user_formats(struct soc_camera_device *icd)
{
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	int i, fmts = 0;

	if (!ici->ops->get_formats)
		/*
		 * Fallback mode - the host will have to serve all
		 * sensor-provided formats one-to-one to the user
		 */
		fmts = icd->num_formats;
	else
		/*
		 * First pass - only count formats this host-sensor
		 * configuration can provide
		 */
		for (i = 0; i < icd->num_formats; i++)
			fmts += ici->ops->get_formats(icd, i, NULL);

	if (!fmts)
		return -ENXIO;

	icd->user_formats =
		vmalloc(fmts * sizeof(struct soc_camera_format_xlate));
	if (!icd->user_formats)
		return -ENOMEM;

	icd->num_user_formats = fmts;

	dev_dbg(&icd->dev, "Found %d supported formats.\n", fmts);

	/* Second pass - actually fill data formats */
243
	fmts = 0;
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
	for (i = 0; i < icd->num_formats; i++)
		if (!ici->ops->get_formats) {
			icd->user_formats[i].host_fmt = icd->formats + i;
			icd->user_formats[i].cam_fmt = icd->formats + i;
			icd->user_formats[i].buswidth = icd->formats[i].depth;
		} else {
			fmts += ici->ops->get_formats(icd, i,
						      &icd->user_formats[fmts]);
		}

	icd->current_fmt = icd->user_formats[0].host_fmt;

	return 0;
}

259
/* Always entered with .video_lock held */
260 261
static void soc_camera_free_user_formats(struct soc_camera_device *icd)
{
262
	icd->current_fmt = NULL;
263
	vfree(icd->user_formats);
264
	icd->user_formats = NULL;
265 266
}

267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
/* Called with .vb_lock held */
static int soc_camera_set_fmt(struct soc_camera_file *icf,
			      struct v4l2_format *f)
{
	struct soc_camera_device *icd = icf->icd;
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	struct v4l2_pix_format *pix = &f->fmt.pix;
	int ret;

	/* We always call try_fmt() before set_fmt() or set_crop() */
	ret = ici->ops->try_fmt(icd, f);
	if (ret < 0)
		return ret;

	ret = ici->ops->set_fmt(icd, f);
	if (ret < 0) {
		return ret;
	} else if (!icd->current_fmt ||
		   icd->current_fmt->fourcc != pix->pixelformat) {
286
		dev_err(ici->v4l2_dev.dev,
287 288 289 290 291 292
			"Host driver hasn't set up current format correctly!\n");
		return -EINVAL;
	}

	icd->width		= pix->width;
	icd->height		= pix->height;
293 294 295
	icf->vb_vidq.field	=
		icd->field	= pix->field;

296 297 298 299 300 301 302 303 304 305 306
	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
		dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
			 f->type);

	dev_dbg(&icd->dev, "set width: %d height: %d\n",
		icd->width, icd->height);

	/* set physical bus parameters */
	return ici->ops->set_bus_param(icd, pix->pixelformat);
}

307
static int soc_camera_open(struct file *file)
308
{
309 310 311
	struct video_device *vdev = video_devdata(file);
	struct soc_camera_device *icd = container_of(vdev->parent, struct soc_camera_device, dev);
	struct soc_camera_link *icl = to_soc_camera_link(icd);
312
	struct soc_camera_host *ici;
313 314 315
	struct soc_camera_file *icf;
	int ret;

316 317 318 319
	if (!icd->ops)
		/* No device driver attached */
		return -ENODEV;

320
	ici = to_soc_camera_host(icd->dev.parent);
321

322 323 324 325
	icf = vmalloc(sizeof(*icf));
	if (!icf)
		return -ENOMEM;

326
	if (!try_module_get(ici->ops->owner)) {
327 328 329 330 331
		dev_err(&icd->dev, "Couldn't lock capture bus driver.\n");
		ret = -EINVAL;
		goto emgi;
	}

332
	/* Protect against icd->ops->remove() until we module_get() both drivers. */
333 334
	mutex_lock(&icd->video_lock);

335
	icf->icd = icd;
336 337
	icd->use_count++;

338 339
	/* Now we really have to activate the camera */
	if (icd->use_count == 1) {
340
		/* Restore parameters before the last close() per V4L2 API */
341 342 343
		struct v4l2_format f = {
			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
			.fmt.pix = {
344 345 346
				.width		= icd->width,
				.height		= icd->height,
				.field		= icd->field,
347 348 349
			},
		};

350 351 352 353 354 355 356
		ret = soc_camera_init_user_formats(icd);
		if (ret < 0)
			goto eiufmt;

		f.fmt.pix.pixelformat	= icd->current_fmt->fourcc;
		f.fmt.pix.colorspace	= icd->current_fmt->colorspace;

357 358 359 360 361 362 363 364 365 366
		if (icl->power) {
			ret = icl->power(icd->pdev, 1);
			if (ret < 0)
				goto epower;
		}

		/* The camera could have been already on, try to reset */
		if (icl->reset)
			icl->reset(icd->pdev);

367
		ret = ici->ops->add(icd);
368 369 370 371
		if (ret < 0) {
			dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
			goto eiciadd;
		}
372

373 374 375 376 377 378
		if (icd->ops->init) {
			ret = icd->ops->init(icd);
			if (ret < 0)
				goto einit;
		}

379 380 381 382
		/* Try to configure with default parameters */
		ret = soc_camera_set_fmt(icf, &f);
		if (ret < 0)
			goto esfmt;
383 384
	}

385 386 387
	file->private_data = icf;
	dev_dbg(&icd->dev, "camera device open\n");

388
	ici->ops->init_videobuf(&icf->vb_vidq, icd);
389

390 391
	mutex_unlock(&icd->video_lock);

392 393
	return 0;

394
	/*
395
	 * First five errors are entered with the .video_lock held
396 397 398
	 * and use_count == 1
	 */
esfmt:
399 400 401
	if (icd->ops->release)
		icd->ops->release(icd);
einit:
402
	ici->ops->remove(icd);
403
eiciadd:
404 405 406
	if (icl->power)
		icl->power(icd->pdev, 0);
epower:
407 408
	soc_camera_free_user_formats(icd);
eiufmt:
409
	icd->use_count--;
410
	mutex_unlock(&icd->video_lock);
411
	module_put(ici->ops->owner);
412 413 414 415 416
emgi:
	vfree(icf);
	return ret;
}

417
static int soc_camera_close(struct file *file)
418 419 420 421 422 423
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	struct video_device *vdev = icd->vdev;

424
	mutex_lock(&icd->video_lock);
425
	icd->use_count--;
426
	if (!icd->use_count) {
427 428 429 430
		struct soc_camera_link *icl = to_soc_camera_link(icd);

		if (icd->ops->release)
			icd->ops->release(icd);
431
		ici->ops->remove(icd);
432 433
		if (icl->power)
			icl->power(icd->pdev, 0);
434 435
		soc_camera_free_user_formats(icd);
	}
436

437 438
	mutex_unlock(&icd->video_lock);

439
	module_put(ici->ops->owner);
440

441
	vfree(icf);
442

443
	dev_dbg(vdev->parent, "camera device close\n");
444 445 446 447

	return 0;
}

448
static ssize_t soc_camera_read(struct file *file, char __user *buf,
449
			       size_t count, loff_t *ppos)
450 451 452 453 454 455
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
	struct video_device *vdev = icd->vdev;
	int err = -EINVAL;

456
	dev_err(vdev->parent, "camera device read not implemented\n");
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482

	return err;
}

static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
	int err;

	dev_dbg(&icd->dev, "mmap called, vma=0x%08lx\n", (unsigned long)vma);

	err = videobuf_mmap_mapper(&icf->vb_vidq, vma);

	dev_dbg(&icd->dev, "vma start=0x%08lx, size=%ld, ret=%d\n",
		(unsigned long)vma->vm_start,
		(unsigned long)vma->vm_end - (unsigned long)vma->vm_start,
		err);

	return err;
}

static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
483
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
484 485 486 487 488 489

	if (list_empty(&icf->vb_vidq.stream)) {
		dev_err(&icd->dev, "Trying to poll with no queued buffers!\n");
		return POLLERR;
	}

490
	return ici->ops->poll(file, pt);
491 492
}

493
static struct v4l2_file_operations soc_camera_fops = {
494 495 496 497 498 499 500 501 502
	.owner		= THIS_MODULE,
	.open		= soc_camera_open,
	.release	= soc_camera_close,
	.ioctl		= video_ioctl2,
	.read		= soc_camera_read,
	.mmap		= soc_camera_mmap,
	.poll		= soc_camera_poll,
};

503
static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
504
				    struct v4l2_format *f)
505 506 507 508 509 510 511
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
	int ret;

	WARN_ON(priv != file->private_data);

512 513 514 515 516 517 518 519
	mutex_lock(&icf->vb_vidq.vb_lock);

	if (videobuf_queue_is_busy(&icf->vb_vidq)) {
		dev_err(&icd->dev, "S_FMT denied: queue busy\n");
		ret = -EBUSY;
		goto unlock;
	}

520
	ret = soc_camera_set_fmt(icf, f);
521 522 523 524 525

unlock:
	mutex_unlock(&icf->vb_vidq.vb_lock);

	return ret;
526 527
}

528
static int soc_camera_enum_fmt_vid_cap(struct file *file, void  *priv,
529
				       struct v4l2_fmtdesc *f)
530 531 532 533 534 535 536
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
	const struct soc_camera_data_format *format;

	WARN_ON(priv != file->private_data);

537
	if (f->index >= icd->num_user_formats)
538 539
		return -EINVAL;

540
	format = icd->user_formats[f->index].host_fmt;
541 542 543 544 545 546

	strlcpy(f->description, format->name, sizeof(f->description));
	f->pixelformat = format->fourcc;
	return 0;
}

547
static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
548
				    struct v4l2_format *f)
549 550 551
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
552
	struct v4l2_pix_format *pix = &f->fmt.pix;
553 554 555

	WARN_ON(priv != file->private_data);

556 557 558 559 560
	pix->width		= icd->width;
	pix->height		= icd->height;
	pix->field		= icf->vb_vidq.field;
	pix->pixelformat	= icd->current_fmt->fourcc;
	pix->bytesperline	= pix->width *
561
		DIV_ROUND_UP(icd->current_fmt->depth, 8);
562
	pix->sizeimage		= pix->height * pix->bytesperline;
563 564 565 566 567 568 569 570 571 572
	dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n",
		icd->current_fmt->fourcc);
	return 0;
}

static int soc_camera_querycap(struct file *file, void  *priv,
			       struct v4l2_capability *cap)
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
573
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
574 575 576 577

	WARN_ON(priv != file->private_data);

	strlcpy(cap->driver, ici->drv_name, sizeof(cap->driver));
578
	return ici->ops->querycap(ici, cap);
579 580 581 582 583 584 585
}

static int soc_camera_streamon(struct file *file, void *priv,
			       enum v4l2_buf_type i)
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
586
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
587
	int ret;
588 589 590 591 592 593

	WARN_ON(priv != file->private_data);

	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
		return -EINVAL;

594 595
	mutex_lock(&icd->video_lock);

596
	v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, video, s_stream, 1);
597 598

	/* This calls buf_queue from host driver's videobuf_queue_ops */
599 600 601 602 603
	ret = videobuf_streamon(&icf->vb_vidq);

	mutex_unlock(&icd->video_lock);

	return ret;
604 605 606 607 608 609 610
}

static int soc_camera_streamoff(struct file *file, void *priv,
				enum v4l2_buf_type i)
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
611
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
612 613 614 615 616 617

	WARN_ON(priv != file->private_data);

	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
		return -EINVAL;

618 619
	mutex_lock(&icd->video_lock);

620 621 622 623
	/* This calls buf_release from host driver's videobuf_queue_ops for all
	 * remaining buffers. When the last buffer is freed, stop capture */
	videobuf_streamoff(&icf->vb_vidq);

624
	v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, video, s_stream, 0);
625

626 627
	mutex_unlock(&icd->video_lock);

628 629 630 631 632 633 634 635
	return 0;
}

static int soc_camera_queryctrl(struct file *file, void *priv,
				struct v4l2_queryctrl *qc)
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
636
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
637 638 639 640 641 642 643
	int i;

	WARN_ON(priv != file->private_data);

	if (!qc->id)
		return -EINVAL;

644 645 646 647 648 649 650 651 652
	/* First check host controls */
	for (i = 0; i < ici->ops->num_controls; i++)
		if (qc->id == ici->ops->controls[i].id) {
			memcpy(qc, &(ici->ops->controls[i]),
				sizeof(*qc));
			return 0;
		}

	/* Then device controls */
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667
	for (i = 0; i < icd->ops->num_controls; i++)
		if (qc->id == icd->ops->controls[i].id) {
			memcpy(qc, &(icd->ops->controls[i]),
				sizeof(*qc));
			return 0;
		}

	return -EINVAL;
}

static int soc_camera_g_ctrl(struct file *file, void *priv,
			     struct v4l2_control *ctrl)
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
668
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
669
	int ret;
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685

	WARN_ON(priv != file->private_data);

	switch (ctrl->id) {
	case V4L2_CID_GAIN:
		if (icd->gain == (unsigned short)~0)
			return -EINVAL;
		ctrl->value = icd->gain;
		return 0;
	case V4L2_CID_EXPOSURE:
		if (icd->exposure == (unsigned short)~0)
			return -EINVAL;
		ctrl->value = icd->exposure;
		return 0;
	}

686 687 688 689 690 691
	if (ici->ops->get_ctrl) {
		ret = ici->ops->get_ctrl(icd, ctrl);
		if (ret != -ENOIOCTLCMD)
			return ret;
	}

692
	return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_ctrl, ctrl);
693 694 695 696 697 698 699
}

static int soc_camera_s_ctrl(struct file *file, void *priv,
			     struct v4l2_control *ctrl)
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
700
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
701
	int ret;
702 703 704

	WARN_ON(priv != file->private_data);

705 706 707 708 709 710
	if (ici->ops->set_ctrl) {
		ret = ici->ops->set_ctrl(icd, ctrl);
		if (ret != -ENOIOCTLCMD)
			return ret;
	}

711
	return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, s_ctrl, ctrl);
712 713 714 715 716 717 718 719 720 721 722 723 724 725 726
}

static int soc_camera_cropcap(struct file *file, void *fh,
			      struct v4l2_cropcap *a)
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;

	a->type				= V4L2_BUF_TYPE_VIDEO_CAPTURE;
	a->bounds.left			= icd->x_min;
	a->bounds.top			= icd->y_min;
	a->bounds.width			= icd->width_max;
	a->bounds.height		= icd->height_max;
	a->defrect.left			= icd->x_min;
	a->defrect.top			= icd->y_min;
727 728
	a->defrect.width		= DEFAULT_WIDTH;
	a->defrect.height		= DEFAULT_HEIGHT;
729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754
	a->pixelaspect.numerator	= 1;
	a->pixelaspect.denominator	= 1;

	return 0;
}

static int soc_camera_g_crop(struct file *file, void *fh,
			     struct v4l2_crop *a)
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;

	a->type		= V4L2_BUF_TYPE_VIDEO_CAPTURE;
	a->c.left	= icd->x_current;
	a->c.top	= icd->y_current;
	a->c.width	= icd->width;
	a->c.height	= icd->height;

	return 0;
}

static int soc_camera_s_crop(struct file *file, void *fh,
			     struct v4l2_crop *a)
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
755
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
756 757 758 759 760
	int ret;

	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
		return -EINVAL;

761 762 763
	/* Cropping is allowed during a running capture, guard consistency */
	mutex_lock(&icf->vb_vidq.vb_lock);

764
	ret = ici->ops->set_crop(icd, &a->c);
765 766 767 768 769 770 771
	if (!ret) {
		icd->width	= a->c.width;
		icd->height	= a->c.height;
		icd->x_current	= a->c.left;
		icd->y_current	= a->c.top;
	}

772 773
	mutex_unlock(&icf->vb_vidq.vb_lock);

774 775 776 777
	return ret;
}

static int soc_camera_g_chip_ident(struct file *file, void *fh,
778
				   struct v4l2_dbg_chip_ident *id)
779 780 781
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
782
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
783

784
	return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_chip_ident, id);
785 786 787 788
}

#ifdef CONFIG_VIDEO_ADV_DEBUG
static int soc_camera_g_register(struct file *file, void *fh,
789
				 struct v4l2_dbg_register *reg)
790 791 792
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
793
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
794

795
	return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_register, reg);
796 797 798
}

static int soc_camera_s_register(struct file *file, void *fh,
799
				 struct v4l2_dbg_register *reg)
800 801 802
{
	struct soc_camera_file *icf = file->private_data;
	struct soc_camera_device *icd = icf->icd;
803
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
804

805
	return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, s_register, reg);
806 807 808 809 810 811 812 813 814 815 816 817
}
#endif

/* So far this function cannot fail */
static void scan_add_host(struct soc_camera_host *ici)
{
	struct soc_camera_device *icd;

	mutex_lock(&list_lock);

	list_for_each_entry(icd, &devices, list) {
		if (icd->iface == ici->nr) {
818
			int ret;
819
			icd->dev.parent = ici->v4l2_dev.dev;
820 821 822 823 824 825 826 827
			dev_set_name(&icd->dev, "%u-%u", icd->iface,
				     icd->devnum);
			ret = device_register(&icd->dev);
			if (ret < 0) {
				icd->dev.parent = NULL;
				dev_err(&icd->dev,
					"Cannot register device: %d\n", ret);
			}
828 829 830 831 832 833
		}
	}

	mutex_unlock(&list_lock);
}

834 835 836
#ifdef CONFIG_I2C_BOARDINFO
static int soc_camera_init_i2c(struct soc_camera_device *icd,
			       struct soc_camera_link *icl)
837
{
838
	struct i2c_client *client;
839
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
840
	struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id);
841
	struct v4l2_subdev *subdev;
842
	int ret;
843

844 845 846 847 848 849
	if (!adap) {
		ret = -ENODEV;
		dev_err(&icd->dev, "Cannot get I2C adapter #%d. No driver?\n",
			icl->i2c_adapter_id);
		goto ei2cga;
	}
850

851
	icl->board_info->platform_data = icd;
852

853 854 855
	subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
				icl->module_name, icl->board_info, NULL);
	if (!subdev) {
856 857
		ret = -ENOMEM;
		goto ei2cnd;
858 859
	}

860 861 862
	subdev->grp_id = (__u32)icd;
	client = subdev->priv;

863 864
	/* Use to_i2c_client(dev) to recover the i2c client */
	dev_set_drvdata(&icd->dev, &client->dev);
865

866 867 868 869
	return 0;
ei2cnd:
	i2c_put_adapter(adap);
ei2cga:
870 871 872
	return ret;
}

873 874 875 876 877
static void soc_camera_free_i2c(struct soc_camera_device *icd)
{
	struct i2c_client *client =
		to_i2c_client(to_soc_camera_control(icd));
	dev_set_drvdata(&icd->dev, NULL);
878
	v4l2_device_unregister_subdev(i2c_get_clientdata(client));
879 880 881 882 883 884 885 886
	i2c_unregister_device(client);
	i2c_put_adapter(client->adapter);
}
#else
#define soc_camera_init_i2c(icd, icl)	(-ENODEV)
#define soc_camera_free_i2c(icd)	do {} while (0)
#endif

887
static int soc_camera_video_start(struct soc_camera_device *icd);
888 889
static int video_dev_create(struct soc_camera_device *icd);
/* Called during host-driver probe */
890 891 892
static int soc_camera_probe(struct device *dev)
{
	struct soc_camera_device *icd = to_soc_camera_dev(dev);
893
	struct soc_camera_host *ici = to_soc_camera_host(dev->parent);
894
	struct soc_camera_link *icl = to_soc_camera_link(icd);
895
	struct device *control = NULL;
896 897
	int ret;

898
	dev_info(dev, "Probing %s\n", dev_name(dev));
899

900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917
	if (icl->power) {
		ret = icl->power(icd->pdev, 1);
		if (ret < 0) {
			dev_err(dev,
				"Platform failed to power-on the camera.\n");
			goto epower;
		}
	}

	/* The camera could have been already on, try to reset */
	if (icl->reset)
		icl->reset(icd->pdev);

	ret = ici->ops->add(icd);
	if (ret < 0)
		goto eadd;

	/* Must have icd->vdev before registering the device */
918 919 920
	ret = video_dev_create(icd);
	if (ret < 0)
		goto evdc;
921

922 923 924 925 926 927
	/* Non-i2c cameras, e.g., soc_camera_platform, have no board_info */
	if (icl->board_info) {
		ret = soc_camera_init_i2c(icd, icl);
		if (ret < 0)
			goto eadddev;
	} else if (!icl->add_device || !icl->del_device) {
928
		ret = -EINVAL;
929 930
		goto eadddev;
	} else {
931 932 933
		if (icl->module_name)
			ret = request_module(icl->module_name);

934 935 936
		ret = icl->add_device(icl, &icd->dev);
		if (ret < 0)
			goto eadddev;
937

938 939 940 941 942 943 944
		/* FIXME: this is racy, have to use driver-binding notification */
		control = to_soc_camera_control(icd);
		if (!control || !control->driver ||
		    !try_module_get(control->driver->owner)) {
			icl->del_device(icl);
			goto enodrv;
		}
945
	}
946

947 948 949 950 951 952 953
	/* ..._video_start() will create a device node, so we have to protect */
	mutex_lock(&icd->video_lock);

	ret = soc_camera_video_start(icd);
	if (ret < 0)
		goto evidstart;

954 955 956 957 958
	/* Do we have to sysfs_remove_link() before device_unregister()? */
	if (to_soc_camera_control(icd) &&
	    sysfs_create_link(&icd->dev.kobj, &to_soc_camera_control(icd)->kobj,
			      "control"))
		dev_warn(&icd->dev, "Failed creating the control symlink\n");
959

960 961 962 963 964 965
	ici->ops->remove(icd);

	if (icl->power)
		icl->power(icd->pdev, 0);

	mutex_unlock(&icd->video_lock);
966

967
	return 0;
968

969 970 971
evidstart:
	mutex_unlock(&icd->video_lock);
	if (icl->board_info) {
972
		soc_camera_free_i2c(icd);
973
	} else {
974
		icl->del_device(icl);
975 976 977
		module_put(control->driver->owner);
	}
enodrv:
978 979 980
eadddev:
	video_device_release(icd->vdev);
evdc:
981 982 983 984 985
	ici->ops->remove(icd);
eadd:
	if (icl->power)
		icl->power(icd->pdev, 0);
epower:
986 987 988 989 990 991 992 993
	return ret;
}

/* This is called on device_unregister, which only means we have to disconnect
 * from the host, but not remove ourselves from the device list */
static int soc_camera_remove(struct device *dev)
{
	struct soc_camera_device *icd = to_soc_camera_dev(dev);
994 995
	struct soc_camera_link *icl = to_soc_camera_link(icd);
	struct video_device *vdev = icd->vdev;
996

997
	BUG_ON(!dev->parent);
998

999 1000 1001 1002 1003 1004 1005
	if (vdev) {
		mutex_lock(&icd->video_lock);
		video_unregister_device(vdev);
		icd->vdev = NULL;
		mutex_unlock(&icd->video_lock);
	}

1006
	if (icl->board_info) {
1007
		soc_camera_free_i2c(icd);
1008 1009 1010 1011 1012 1013 1014 1015
	} else {
		struct device_driver *drv = to_soc_camera_control(icd) ?
			to_soc_camera_control(icd)->driver : NULL;
		if (drv) {
			icl->del_device(icl);
			module_put(drv->owner);
		}
	}
1016

1017 1018 1019
	return 0;
}

1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
static int soc_camera_suspend(struct device *dev, pm_message_t state)
{
	struct soc_camera_device *icd = to_soc_camera_dev(dev);
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	int ret = 0;

	if (ici->ops->suspend)
		ret = ici->ops->suspend(icd, state);

	return ret;
}

static int soc_camera_resume(struct device *dev)
{
	struct soc_camera_device *icd = to_soc_camera_dev(dev);
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	int ret = 0;

	if (ici->ops->resume)
		ret = ici->ops->resume(icd);

	return ret;
}

1044 1045 1046 1047
static struct bus_type soc_camera_bus_type = {
	.name		= "soc-camera",
	.probe		= soc_camera_probe,
	.remove		= soc_camera_remove,
1048 1049
	.suspend	= soc_camera_suspend,
	.resume		= soc_camera_resume,
1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061
};

static struct device_driver ic_drv = {
	.name	= "camera",
	.bus	= &soc_camera_bus_type,
	.owner	= THIS_MODULE,
};

static void dummy_release(struct device *dev)
{
}

1062
int soc_camera_host_register(struct soc_camera_host *ici)
1063 1064
{
	struct soc_camera_host *ix;
1065
	int ret;
1066

1067 1068 1069
	if (!ici || !ici->ops ||
	    !ici->ops->try_fmt ||
	    !ici->ops->set_fmt ||
1070
	    !ici->ops->set_crop ||
1071 1072 1073 1074 1075 1076
	    !ici->ops->set_bus_param ||
	    !ici->ops->querycap ||
	    !ici->ops->init_videobuf ||
	    !ici->ops->reqbufs ||
	    !ici->ops->add ||
	    !ici->ops->remove ||
1077
	    !ici->ops->poll ||
1078
	    !ici->v4l2_dev.dev)
1079 1080 1081 1082 1083
		return -EINVAL;

	mutex_lock(&list_lock);
	list_for_each_entry(ix, &hosts, list) {
		if (ix->nr == ici->nr) {
1084 1085
			ret = -EBUSY;
			goto edevreg;
1086 1087 1088
		}
	}

1089 1090 1091
	ret = v4l2_device_register(ici->v4l2_dev.dev, &ici->v4l2_dev);
	if (ret < 0)
		goto edevreg;
1092

1093 1094 1095 1096 1097 1098
	list_add_tail(&ici->list, &hosts);
	mutex_unlock(&list_lock);

	scan_add_host(ici);

	return 0;
1099 1100 1101 1102

edevreg:
	mutex_unlock(&list_lock);
	return ret;
1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115
}
EXPORT_SYMBOL(soc_camera_host_register);

/* Unregister all clients! */
void soc_camera_host_unregister(struct soc_camera_host *ici)
{
	struct soc_camera_device *icd;

	mutex_lock(&list_lock);

	list_del(&ici->list);

	list_for_each_entry(icd, &devices, list) {
1116
		if (icd->iface == ici->nr) {
1117
			/* The bus->remove will be called */
1118 1119
			device_unregister(&icd->dev);
			/* Not before device_unregister(), .remove
1120
			 * needs parent to call ici->ops->remove() */
1121
			icd->dev.parent = NULL;
1122 1123 1124

			/* If the host module is loaded again, device_register()
			 * would complain "already initialised" */
1125 1126 1127 1128 1129 1130
			memset(&icd->dev.kobj, 0, sizeof(icd->dev.kobj));
		}
	}

	mutex_unlock(&list_lock);

1131
	v4l2_device_unregister(&ici->v4l2_dev);
1132 1133 1134 1135
}
EXPORT_SYMBOL(soc_camera_host_unregister);

/* Image capture device */
1136
static int soc_camera_device_register(struct soc_camera_device *icd)
1137 1138 1139 1140 1141 1142
{
	struct soc_camera_device *ix;
	int num = -1, i;

	for (i = 0; i < 256 && num < 0; i++) {
		num = i;
1143
		/* Check if this index is available on this interface */
1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159
		list_for_each_entry(ix, &devices, list) {
			if (ix->iface == icd->iface && ix->devnum == i) {
				num = -1;
				break;
			}
		}
	}

	if (num < 0)
		/* ok, we have 256 cameras on this host...
		 * man, stay reasonable... */
		return -ENOMEM;

	icd->devnum = num;
	icd->dev.bus = &soc_camera_bus_type;

1160 1161 1162
	icd->dev.release	= dummy_release;
	icd->use_count		= 0;
	icd->host_priv		= NULL;
1163
	mutex_init(&icd->video_lock);
1164

1165 1166 1167
	list_add_tail(&icd->list, &devices);

	return 0;
1168 1169
}

1170
static void soc_camera_device_unregister(struct soc_camera_device *icd)
1171 1172 1173 1174
{
	list_del(&icd->list);
}

1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203
static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
	.vidioc_querycap	 = soc_camera_querycap,
	.vidioc_g_fmt_vid_cap    = soc_camera_g_fmt_vid_cap,
	.vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap,
	.vidioc_s_fmt_vid_cap    = soc_camera_s_fmt_vid_cap,
	.vidioc_enum_input	 = soc_camera_enum_input,
	.vidioc_g_input		 = soc_camera_g_input,
	.vidioc_s_input		 = soc_camera_s_input,
	.vidioc_s_std		 = soc_camera_s_std,
	.vidioc_reqbufs		 = soc_camera_reqbufs,
	.vidioc_try_fmt_vid_cap  = soc_camera_try_fmt_vid_cap,
	.vidioc_querybuf	 = soc_camera_querybuf,
	.vidioc_qbuf		 = soc_camera_qbuf,
	.vidioc_dqbuf		 = soc_camera_dqbuf,
	.vidioc_streamon	 = soc_camera_streamon,
	.vidioc_streamoff	 = soc_camera_streamoff,
	.vidioc_queryctrl	 = soc_camera_queryctrl,
	.vidioc_g_ctrl		 = soc_camera_g_ctrl,
	.vidioc_s_ctrl		 = soc_camera_s_ctrl,
	.vidioc_cropcap		 = soc_camera_cropcap,
	.vidioc_g_crop		 = soc_camera_g_crop,
	.vidioc_s_crop		 = soc_camera_s_crop,
	.vidioc_g_chip_ident     = soc_camera_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
	.vidioc_g_register	 = soc_camera_g_register,
	.vidioc_s_register	 = soc_camera_s_register,
#endif
};

1204
static int video_dev_create(struct soc_camera_device *icd)
1205 1206
{
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1207
	struct video_device *vdev = video_device_alloc();
1208 1209

	if (!vdev)
1210
		return -ENOMEM;
1211 1212

	strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
1213

1214
	vdev->parent		= &icd->dev;
1215 1216
	vdev->current_norm	= V4L2_STD_UNKNOWN;
	vdev->fops		= &soc_camera_fops;
1217
	vdev->ioctl_ops		= &soc_camera_ioctl_ops;
1218 1219
	vdev->release		= video_device_release;
	vdev->minor		= -1;
1220
	vdev->tvnorms		= V4L2_STD_UNKNOWN;
1221 1222 1223 1224

	icd->vdev = vdev;

	return 0;
1225
}
1226

1227
/*
1228
 * Called from soc_camera_probe() above (with .video_lock held???)
1229
 */
1230
static int soc_camera_video_start(struct soc_camera_device *icd)
1231 1232
{
	const struct v4l2_queryctrl *qctrl;
1233
	int ret;
1234 1235 1236 1237 1238 1239 1240 1241 1242

	if (!icd->dev.parent)
		return -ENODEV;

	if (!icd->ops ||
	    !icd->ops->query_bus_param ||
	    !icd->ops->set_bus_param)
		return -EINVAL;

1243 1244 1245 1246 1247 1248
	ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER,
				    icd->vdev->minor);
	if (ret < 0) {
		dev_err(&icd->dev, "video_register_device failed: %d\n", ret);
		return ret;
	}
1249 1250 1251 1252 1253 1254

	qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_GAIN);
	icd->gain = qctrl ? qctrl->default_value : (unsigned short)~0;
	qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
	icd->exposure = qctrl ? qctrl->default_value : (unsigned short)~0;

1255
	return 0;
1256 1257
}

1258
static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
1259
{
1260 1261
	struct soc_camera_link *icl = pdev->dev.platform_data;
	struct soc_camera_device *icd;
1262
	int ret;
1263

1264 1265
	if (!icl)
		return -EINVAL;
1266

1267 1268 1269
	icd = kzalloc(sizeof(*icd), GFP_KERNEL);
	if (!icd)
		return -ENOMEM;
1270

1271
	icd->iface = icl->bus_id;
1272
	icd->pdev = &pdev->dev;
1273 1274
	platform_set_drvdata(pdev, icd);
	icd->dev.platform_data = icl;
1275

1276 1277 1278
	ret = soc_camera_device_register(icd);
	if (ret < 0)
		goto escdevreg;
1279

1280
	return 0;
1281

1282 1283
escdevreg:
	kfree(icd);
1284

1285
	return ret;
1286
}
1287

1288 1289 1290 1291
/* Only called on rmmod for each platform device, since they are not
 * hot-pluggable. Now we know, that all our users - hosts and devices have
 * been unloaded already */
static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
1292
{
1293
	struct soc_camera_device *icd = platform_get_drvdata(pdev);
1294

1295
	if (!icd)
1296 1297
		return -EINVAL;

1298
	soc_camera_device_unregister(icd);
1299

1300
	kfree(icd);
1301

1302 1303 1304 1305
	return 0;
}

static struct platform_driver __refdata soc_camera_pdrv = {
1306 1307 1308 1309
	.remove  = __devexit_p(soc_camera_pdrv_remove),
	.driver  = {
		.name	= "soc-camera-pdrv",
		.owner	= THIS_MODULE,
1310 1311 1312
	},
};

1313 1314 1315 1316 1317 1318 1319 1320 1321
static int __init soc_camera_init(void)
{
	int ret = bus_register(&soc_camera_bus_type);
	if (ret)
		return ret;
	ret = driver_register(&ic_drv);
	if (ret)
		goto edrvr;

1322
	ret = platform_driver_probe(&soc_camera_pdrv, soc_camera_pdrv_probe);
1323 1324 1325
	if (ret)
		goto epdr;

1326 1327
	return 0;

1328 1329
epdr:
	driver_unregister(&ic_drv);
1330 1331 1332 1333 1334 1335 1336
edrvr:
	bus_unregister(&soc_camera_bus_type);
	return ret;
}

static void __exit soc_camera_exit(void)
{
1337
	platform_driver_unregister(&soc_camera_pdrv);
1338 1339 1340 1341 1342 1343 1344 1345 1346 1347
	driver_unregister(&ic_drv);
	bus_unregister(&soc_camera_bus_type);
}

module_init(soc_camera_init);
module_exit(soc_camera_exit);

MODULE_DESCRIPTION("Image capture bus driver");
MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
MODULE_LICENSE("GPL");
1348
MODULE_ALIAS("platform:soc-camera-pdrv");