V4L/DVB (13344): soc-camera: properly initialise the device object when reusing
[safe/jmp/linux-2.6] / drivers / media / video / soc_camera.c
index aa6614b..95fdeb2 100644 (file)
@@ -152,12 +152,9 @@ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
 {
        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);
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 
-       return ret;
+       return v4l2_subdev_call(sd, core, s_std, *a);
 }
 
 static int soc_camera_reqbufs(struct file *file, void *priv,
@@ -281,6 +278,9 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd)
        icd->user_formats = NULL;
 }
 
+#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
+       ((x) >> 24) & 0xff
+
 /* Called with .vb_lock held */
 static int soc_camera_set_fmt(struct soc_camera_file *icf,
                              struct v4l2_format *f)
@@ -290,6 +290,9 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
        struct v4l2_pix_format *pix = &f->fmt.pix;
        int ret;
 
+       dev_dbg(&icd->dev, "S_FMT(%c%c%c%c, %ux%u)\n",
+               pixfmtstr(pix->pixelformat), pix->width, pix->height);
+
        /* We always call try_fmt() before set_fmt() or set_crop() */
        ret = ici->ops->try_fmt(icd, f);
        if (ret < 0)
@@ -300,22 +303,22 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
                return ret;
        } else if (!icd->current_fmt ||
                   icd->current_fmt->fourcc != pix->pixelformat) {
-               dev_err(ici->v4l2_dev.dev,
+               dev_err(&icd->dev,
                        "Host driver hasn't set up current format correctly!\n");
                return -EINVAL;
        }
 
-       icd->rect_current.width         = pix->width;
-       icd->rect_current.height        = pix->height;
-       icf->vb_vidq.field              =
-               icd->field              = pix->field;
+       icd->user_width         = pix->width;
+       icd->user_height        = pix->height;
+       icf->vb_vidq.field      =
+               icd->field      = pix->field;
 
        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->rect_current.width, icd->rect_current.height);
+               icd->user_width, icd->user_height);
 
        /* set physical bus parameters */
        return ici->ops->set_bus_param(icd, pix->pixelformat);
@@ -324,7 +327,9 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
 static int soc_camera_open(struct file *file)
 {
        struct video_device *vdev = video_devdata(file);
-       struct soc_camera_device *icd = container_of(vdev->parent, struct soc_camera_device, dev);
+       struct soc_camera_device *icd = container_of(vdev->parent,
+                                                    struct soc_camera_device,
+                                                    dev);
        struct soc_camera_link *icl = to_soc_camera_link(icd);
        struct soc_camera_host *ici;
        struct soc_camera_file *icf;
@@ -346,7 +351,10 @@ static int soc_camera_open(struct file *file)
                goto emgi;
        }
 
-       /* Protect against icd->ops->remove() until we module_get() both drivers. */
+       /*
+        * Protect against icd->ops->remove() until we module_get() both
+        * drivers.
+        */
        mutex_lock(&icd->video_lock);
 
        icf->icd = icd;
@@ -358,8 +366,8 @@ static int soc_camera_open(struct file *file)
                struct v4l2_format f = {
                        .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
                        .fmt.pix = {
-                               .width          = icd->rect_current.width,
-                               .height         = icd->rect_current.height,
+                               .width          = icd->user_width,
+                               .height         = icd->user_height,
                                .field          = icd->field,
                                .pixelformat    = icd->current_fmt->fourcc,
                                .colorspace     = icd->current_fmt->colorspace,
@@ -382,12 +390,6 @@ static int soc_camera_open(struct file *file)
                        goto eiciadd;
                }
 
-               if (icd->ops->init) {
-                       ret = icd->ops->init(icd);
-                       if (ret < 0)
-                               goto einit;
-               }
-
                /* Try to configure with default parameters */
                ret = soc_camera_set_fmt(icf, &f);
                if (ret < 0)
@@ -408,9 +410,6 @@ static int soc_camera_open(struct file *file)
         * and use_count == 1
         */
 esfmt:
-       if (icd->ops->release)
-               icd->ops->release(icd);
-einit:
        ici->ops->remove(icd);
 eiciadd:
        if (icl->power)
@@ -429,15 +428,12 @@ static int soc_camera_close(struct file *file)
        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;
 
        mutex_lock(&icd->video_lock);
        icd->use_count--;
        if (!icd->use_count) {
                struct soc_camera_link *icl = to_soc_camera_link(icd);
 
-               if (icd->ops->release)
-                       icd->ops->release(icd);
                ici->ops->remove(icd);
                if (icl->power)
                        icl->power(icd->pdev, 0);
@@ -449,7 +445,7 @@ static int soc_camera_close(struct file *file)
 
        vfree(icf);
 
-       dev_dbg(vdev->parent, "camera device close\n");
+       dev_dbg(&icd->dev, "camera device close\n");
 
        return 0;
 }
@@ -459,10 +455,9 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf,
 {
        struct soc_camera_file *icf = file->private_data;
        struct soc_camera_device *icd = icf->icd;
-       struct video_device *vdev = icd->vdev;
        int err = -EINVAL;
 
-       dev_err(vdev->parent, "camera device read not implemented\n");
+       dev_err(&icd->dev, "camera device read not implemented\n");
 
        return err;
 }
@@ -520,8 +515,8 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
 
        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");
+       if (icf->vb_vidq.bufs[0]) {
+               dev_err(&icd->dev, "S_FMT denied: queue initialised\n");
                ret = -EBUSY;
                goto unlock;
        }
@@ -562,8 +557,8 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
 
        WARN_ON(priv != file->private_data);
 
-       pix->width              = icd->rect_current.width;
-       pix->height             = icd->rect_current.height;
+       pix->width              = icd->user_width;
+       pix->height             = icd->user_height;
        pix->field              = icf->vb_vidq.field;
        pix->pixelformat        = icd->current_fmt->fourcc;
        pix->bytesperline       = pix->width *
@@ -592,7 +587,7 @@ static int soc_camera_streamon(struct file *file, void *priv,
 {
        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 v4l2_subdev *sd = soc_camera_to_subdev(icd);
        int ret;
 
        WARN_ON(priv != file->private_data);
@@ -602,7 +597,7 @@ static int soc_camera_streamon(struct file *file, void *priv,
 
        mutex_lock(&icd->video_lock);
 
-       v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, video, s_stream, 1);
+       v4l2_subdev_call(sd, video, s_stream, 1);
 
        /* This calls buf_queue from host driver's videobuf_queue_ops */
        ret = videobuf_streamon(&icf->vb_vidq);
@@ -617,7 +612,7 @@ static int soc_camera_streamoff(struct file *file, void *priv,
 {
        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 v4l2_subdev *sd = soc_camera_to_subdev(icd);
 
        WARN_ON(priv != file->private_data);
 
@@ -630,7 +625,7 @@ static int soc_camera_streamoff(struct file *file, void *priv,
         * remaining buffers. When the last buffer is freed, stop capture */
        videobuf_streamoff(&icf->vb_vidq);
 
-       v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, video, s_stream, 0);
+       v4l2_subdev_call(sd, video, s_stream, 0);
 
        mutex_unlock(&icd->video_lock);
 
@@ -675,30 +670,18 @@ static int soc_camera_g_ctrl(struct file *file, void *priv,
        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 v4l2_subdev *sd = soc_camera_to_subdev(icd);
        int ret;
 
        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;
-       }
-
        if (ici->ops->get_ctrl) {
                ret = ici->ops->get_ctrl(icd, ctrl);
                if (ret != -ENOIOCTLCMD)
                        return ret;
        }
 
-       return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_ctrl, ctrl);
+       return v4l2_subdev_call(sd, core, g_ctrl, ctrl);
 }
 
 static int soc_camera_s_ctrl(struct file *file, void *priv,
@@ -707,6 +690,7 @@ static int soc_camera_s_ctrl(struct file *file, void *priv,
        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 v4l2_subdev *sd = soc_camera_to_subdev(icd);
        int ret;
 
        WARN_ON(priv != file->private_data);
@@ -717,7 +701,7 @@ static int soc_camera_s_ctrl(struct file *file, void *priv,
                        return ret;
        }
 
-       return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, s_ctrl, ctrl);
+       return v4l2_subdev_call(sd, core, s_ctrl, ctrl);
 }
 
 static int soc_camera_cropcap(struct file *file, void *fh,
@@ -725,17 +709,9 @@ static int soc_camera_cropcap(struct file *file, void *fh,
 {
        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);
 
-       a->type                         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       a->bounds                       = icd->rect_max;
-       a->defrect.left                 = icd->rect_max.left;
-       a->defrect.top                  = icd->rect_max.top;
-       a->defrect.width                = DEFAULT_WIDTH;
-       a->defrect.height               = DEFAULT_HEIGHT;
-       a->pixelaspect.numerator        = 1;
-       a->pixelaspect.denominator      = 1;
-
-       return 0;
+       return ici->ops->cropcap(icd, a);
 }
 
 static int soc_camera_g_crop(struct file *file, void *fh,
@@ -743,50 +719,54 @@ static int soc_camera_g_crop(struct file *file, void *fh,
 {
        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);
+       int ret;
 
-       a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       a->c    = icd->rect_current;
+       mutex_lock(&icf->vb_vidq.vb_lock);
+       ret = ici->ops->get_crop(icd, a);
+       mutex_unlock(&icf->vb_vidq.vb_lock);
 
-       return 0;
+       return ret;
 }
 
+/*
+ * According to the V4L2 API, drivers shall not update the struct v4l2_crop
+ * argument with the actual geometry, instead, the user shall use G_CROP to
+ * retrieve it. However, we expect camera host and client drivers to update
+ * the argument, which we then use internally, but do not return to the user.
+ */
 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;
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       struct v4l2_rect *rect = &a->c;
+       struct v4l2_crop current_crop;
        int ret;
 
        if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                return -EINVAL;
 
+       dev_dbg(&icd->dev, "S_CROP(%ux%u@%u:%u)\n",
+               rect->width, rect->height, rect->left, rect->top);
+
        /* Cropping is allowed during a running capture, guard consistency */
        mutex_lock(&icf->vb_vidq.vb_lock);
 
-       if (a->c.width > icd->rect_max.width)
-               a->c.width = icd->rect_max.width;
-
-       if (a->c.width < icd->width_min)
-               a->c.width = icd->width_min;
-
-       if (a->c.height > icd->rect_max.height)
-               a->c.height = icd->rect_max.height;
-
-       if (a->c.height < icd->height_min)
-               a->c.height = icd->height_min;
+       /* If get_crop fails, we'll let host and / or client drivers decide */
+       ret = ici->ops->get_crop(icd, &current_crop);
 
-       if (a->c.width + a->c.left > icd->rect_max.width + icd->rect_max.left)
-               a->c.left = icd->rect_max.width + icd->rect_max.left -
-                       a->c.width;
-
-       if (a->c.height + a->c.top > icd->rect_max.height + icd->rect_max.top)
-               a->c.top = icd->rect_max.height + icd->rect_max.top -
-                       a->c.height;
-
-       ret = ici->ops->set_crop(icd, &a->c);
-       if (!ret)
-               icd->rect_current = a->c;
+       /* Prohibit window size change with initialised buffers */
+       if (icf->vb_vidq.bufs[0] && !ret &&
+           (a->c.width != current_crop.c.width ||
+            a->c.height != current_crop.c.height)) {
+               dev_err(&icd->dev,
+                       "S_CROP denied: queue initialised and sizes differ\n");
+               ret = -EBUSY;
+       } else {
+               ret = ici->ops->set_crop(icd, a);
+       }
 
        mutex_unlock(&icf->vb_vidq.vb_lock);
 
@@ -798,9 +778,9 @@ static int soc_camera_g_chip_ident(struct file *file, void *fh,
 {
        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 v4l2_subdev *sd = soc_camera_to_subdev(icd);
 
-       return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_chip_ident, id);
+       return v4l2_subdev_call(sd, core, g_chip_ident, id);
 }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -809,9 +789,9 @@ static int soc_camera_g_register(struct file *file, void *fh,
 {
        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 v4l2_subdev *sd = soc_camera_to_subdev(icd);
 
-       return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, g_register, reg);
+       return v4l2_subdev_call(sd, core, g_register, reg);
 }
 
 static int soc_camera_s_register(struct file *file, void *fh,
@@ -819,9 +799,9 @@ static int soc_camera_s_register(struct file *file, void *fh,
 {
        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 v4l2_subdev *sd = soc_camera_to_subdev(icd);
 
-       return v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, core, s_register, reg);
+       return v4l2_subdev_call(sd, core, s_register, reg);
 }
 #endif
 
@@ -876,7 +856,6 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
                goto ei2cnd;
        }
 
-       subdev->grp_id = (__u32)icd;
        client = subdev->priv;
 
        /* Use to_i2c_client(dev) to recover the i2c client */
@@ -912,6 +891,8 @@ static int soc_camera_probe(struct device *dev)
        struct soc_camera_host *ici = to_soc_camera_host(dev->parent);
        struct soc_camera_link *icl = to_soc_camera_link(icd);
        struct device *control = NULL;
+       struct v4l2_subdev *sd;
+       struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
        int ret;
 
        dev_info(dev, "Probing %s\n", dev_name(dev));
@@ -954,9 +935,12 @@ static int soc_camera_probe(struct device *dev)
                if (ret < 0)
                        goto eadddev;
 
-               /* FIXME: this is racy, have to use driver-binding notification */
+               /*
+                * FIXME: this is racy, have to use driver-binding notification,
+                * when it is available
+                */
                control = to_soc_camera_control(icd);
-               if (!control || !control->driver ||
+               if (!control || !control->driver || !dev_get_drvdata(control) ||
                    !try_module_get(control->driver->owner)) {
                        icl->del_device(icl);
                        goto enodrv;
@@ -968,7 +952,6 @@ static int soc_camera_probe(struct device *dev)
        if (ret < 0)
                goto eiufmt;
 
-       icd->rect_current = icd->rect_max;
        icd->field = V4L2_FIELD_ANY;
 
        /* ..._video_start() will create a device node, so we have to protect */
@@ -978,9 +961,15 @@ static int soc_camera_probe(struct device *dev)
        if (ret < 0)
                goto evidstart;
 
+       /* Try to improve our guess of a reasonable window format */
+       sd = soc_camera_to_subdev(icd);
+       if (!v4l2_subdev_call(sd, video, g_fmt, &f)) {
+               icd->user_width         = f.fmt.pix.width;
+               icd->user_height        = f.fmt.pix.height;
+       }
+
        /* 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,
+       if (sysfs_create_link(&icd->dev.kobj, &to_soc_camera_control(icd)->kobj,
                              "control"))
                dev_warn(&icd->dev, "Failed creating the control symlink\n");
 
@@ -1089,6 +1078,32 @@ static void dummy_release(struct device *dev)
 {
 }
 
+static int default_cropcap(struct soc_camera_device *icd,
+                          struct v4l2_cropcap *a)
+{
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+       return v4l2_subdev_call(sd, video, cropcap, a);
+}
+
+static int default_g_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
+{
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+       return v4l2_subdev_call(sd, video, g_crop, a);
+}
+
+static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
+{
+       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+       return v4l2_subdev_call(sd, video, s_crop, a);
+}
+
+static void soc_camera_device_init(struct device *dev, void *pdata)
+{
+       dev->platform_data      = pdata;
+       dev->bus                = &soc_camera_bus_type;
+       dev->release            = dummy_release;
+}
+
 int soc_camera_host_register(struct soc_camera_host *ici)
 {
        struct soc_camera_host *ix;
@@ -1097,7 +1112,6 @@ int soc_camera_host_register(struct soc_camera_host *ici)
        if (!ici || !ici->ops ||
            !ici->ops->try_fmt ||
            !ici->ops->set_fmt ||
-           !ici->ops->set_crop ||
            !ici->ops->set_bus_param ||
            !ici->ops->querycap ||
            !ici->ops->init_videobuf ||
@@ -1108,6 +1122,13 @@ int soc_camera_host_register(struct soc_camera_host *ici)
            !ici->v4l2_dev.dev)
                return -EINVAL;
 
+       if (!ici->ops->set_crop)
+               ici->ops->set_crop = default_s_crop;
+       if (!ici->ops->get_crop)
+               ici->ops->get_crop = default_g_crop;
+       if (!ici->ops->cropcap)
+               ici->ops->cropcap = default_cropcap;
+
        mutex_lock(&list_lock);
        list_for_each_entry(ix, &hosts, list) {
                if (ix->nr == ici->nr) {
@@ -1144,15 +1165,19 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
 
        list_for_each_entry(icd, &devices, list) {
                if (icd->iface == ici->nr) {
+                       void *pdata = icd->dev.platform_data;
                        /* The bus->remove will be called */
                        device_unregister(&icd->dev);
-                       /* Not before device_unregister(), .remove
-                        * needs parent to call ici->ops->remove() */
-                       icd->dev.parent = NULL;
-
-                       /* If the host module is loaded again, device_register()
-                        * would complain "already initialised" */
-                       memset(&icd->dev.kobj, 0, sizeof(icd->dev.kobj));
+                       /*
+                        * Not before device_unregister(), .remove
+                        * needs parent to call ici->ops->remove().
+                        * If the host module is loaded again, device_register()
+                        * would complain "already initialised," since 2.6.32
+                        * this is also needed to prevent use-after-free of the
+                        * device private data.
+                        */
+                       memset(&icd->dev, 0, sizeof(icd->dev));
+                       soc_camera_device_init(&icd->dev, pdata);
                }
        }
 
@@ -1184,10 +1209,7 @@ static int soc_camera_device_register(struct soc_camera_device *icd)
                 * man, stay reasonable... */
                return -ENOMEM;
 
-       icd->devnum = num;
-       icd->dev.bus = &soc_camera_bus_type;
-
-       icd->dev.release        = dummy_release;
+       icd->devnum             = num;
        icd->use_count          = 0;
        icd->host_priv          = NULL;
        mutex_init(&icd->video_lock);
@@ -1259,7 +1281,6 @@ static int video_dev_create(struct soc_camera_device *icd)
  */
 static int soc_camera_video_start(struct soc_camera_device *icd)
 {
-       const struct v4l2_queryctrl *qctrl;
        int ret;
 
        if (!icd->dev.parent)
@@ -1277,11 +1298,6 @@ static int soc_camera_video_start(struct soc_camera_device *icd)
                return ret;
        }
 
-       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;
-
        return 0;
 }
 
@@ -1301,12 +1317,16 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
        icd->iface = icl->bus_id;
        icd->pdev = &pdev->dev;
        platform_set_drvdata(pdev, icd);
-       icd->dev.platform_data = icl;
 
        ret = soc_camera_device_register(icd);
        if (ret < 0)
                goto escdevreg;
 
+       soc_camera_device_init(&icd->dev, icl);
+
+       icd->user_width         = DEFAULT_WIDTH;
+       icd->user_height        = DEFAULT_HEIGHT;
+
        return 0;
 
 escdevreg: