static int unicam_videobuf_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, unsigned int *count, unsigned int *numplanes, unsigned int sizes[], void *alloc_ctxs[]) { struct soc_camera_device *icd = soc_camera_from_vb2q(vq); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct unicam_camera_dev *unicam_dev = (struct unicam_camera_dev *)ici->priv; int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, icd-> current_fmt->host_fmt); dprintk("-enter"); if (bytes_per_line < 0) return bytes_per_line; *numplanes = 1; unicam_dev->sequence = 0; sizes[0] = bytes_per_line * icd->user_height; alloc_ctxs[0] = unicam_dev->alloc_ctx; if (!*count) *count = 2; iprintk("no_of_buf=%d size=%u", *count, sizes[0]); dprintk("-exit"); return 0; }
static int unicam_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { struct device *dev = icd->dev.parent; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct unicam_camera_dev *unicam_dev = ici->priv; const struct soc_camera_format_xlate *xlate = NULL; struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_mbus_framefmt mf; int ret; u32 skip_frames = 0; dprintk("-enter"); xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); if (!xlate) { dev_warn(dev, "Format %x not found\n", pix->pixelformat); return -EINVAL; } mf.width = pix->width; mf.height = pix->height; mf.field = pix->field; mf.colorspace = pix->colorspace; mf.code = xlate->code; ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); if (mf.code != xlate->code) return -EINVAL; if (ret < 0) { dev_warn(dev, "Failed to configure for format %x\n", pix->pixelformat); return ret; } /*TODO limit here any maximum size */ ret = v4l2_subdev_call(sd, sensor, g_skip_frames, &skip_frames); if (ret < 0) { dev_warn(dev, "sensor driver doesn't implement g_skip_frames operation\n"); dev_warn(dev, "assuming zero skip frames\n"); skip_frames = 0; ret = 0; } unicam_dev->skip_frames = skip_frames; pix->width = mf.width; pix->height = mf.height; pix->field = mf.field; pix->colorspace = mf.colorspace; icd->current_fmt = xlate; iprintk("format set to %c%c%c%c res=%dx%d success=%d", pixfmtstr(pix->pixelformat), pix->width, pix->height, ret); dprintk("-exit"); return ret; }
int boot_dmsg (uint64_t tty, const char *fmt, ...) { va_list ap; int count; va_start (ap, fmt); count = iprintk (tty, 0, (char *) fmt, ap); va_end (ap); return count; }
static int unicam_camera_try_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_mbus_framefmt mf; struct v4l2_format thumb_fmt; struct v4l2_pix_format *thumb_pix; __u32 pixfmt = pix->pixelformat; int thumb=0; int ret; dprintk("-enter"); xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (!xlate) { dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt); return -EINVAL; } pix->sizeimage = pix->height * pix->bytesperline; /* limit to sensor capabilities */ mf.width = pix->width; mf.height = pix->height; mf.field = pix->field; mf.colorspace = pix->colorspace; mf.code = xlate->code; ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); if (ret < 0) return ret; pix->width = mf.width; pix->height = mf.height; pix->colorspace = mf.colorspace; switch (mf.field) { case V4L2_FIELD_ANY: case V4L2_FIELD_NONE: pix->field = V4L2_FIELD_NONE; break; default: dev_err(icd->dev.parent, "Field type %d unsupported.\n", mf.field); return -EINVAL; } /* what format can unicam support */ switch (mf.code) { case V4L2_MBUS_FMT_JPEG_1X8: /* check here if thumbnail is supported and check thumbnail format */ ret = v4l2_subdev_call(sd, core, ioctl, VIDIOC_THUMB_SUPPORTED, (void *)&thumb); if ((!ret) && thumb) { ret = v4l2_subdev_call(sd, core, ioctl, VIDIOC_THUMB_G_FMT, (void *)&thumb_fmt); if (ret < 0) { dev_err(icd->dev.parent, "sensor driver should report thumbnail format\n"); return -EINVAL; } thumb_pix = &thumb_fmt.fmt.pix; switch (thumb_pix->pixelformat) { case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_UYVY: iprintk ("sensor supports thumbnail %c%c%c%c format", pixfmtstr(thumb_pix->pixelformat)); break; default: dev_err(icd->dev.parent, "sensor thumbnail format %c%c%c%c not supported\n", pixfmtstr(thumb_pix->pixelformat)); return -EINVAL; } } else iprintk ("sensor doesnot support thumbnail (thumb=%d, ret=%d)\n", thumb, ret); case V4L2_MBUS_FMT_YUYV8_2X8: case V4L2_MBUS_FMT_UYVY8_2X8: /* Above formats are supported */ break; default: dev_err(icd->dev.parent, "Sensor format code %d unsupported.\n", mf.code); return -EINVAL; } iprintk("trying format=%c%c%c%c res=%dx%d success=%d", pixfmtstr(pixfmt), mf.width, mf.height, ret); dprintk("-exit"); return ret; }
int unicam_videobuf_stop_streaming(struct vb2_queue *q) { struct soc_camera_device *icd = soc_camera_from_vb2q(q); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct unicam_camera_dev *unicam_dev = ici->priv; CSL_CAM_FRAME_st_t cslCamFrame; int ret = 0; unsigned long flags; if (down_interruptible(&unicam_dev->stop_processing_sem) == 0) { if (unicam_dev->streaming) csl_cam_register_display(unicam_dev->cslCamHandle); } else dev_err(unicam_dev->dev, "Unable to dump regs because stop_processing_sem acquire failed\n"); /* grab the lock */ spin_lock_irqsave(&unicam_dev->lock, flags); dprintk("-enter"); dprintk("disabling csi"); iprintk("stopping stream"); if (!unicam_dev->streaming) { dev_err(unicam_dev->dev, "stream already turned off\n"); goto out; } /* * stop streaming before grabing spin lock * since this function can sleep. * */ if (unicam_dev->active) { unicam_dev->stopping = true; spin_unlock_irqrestore(&unicam_dev->lock, flags); ret = down_timeout(&unicam_dev->stop_sem, msecs_to_jiffies(500)); if (ret == -ETIME) pr_err("Unicam: semaphore timed out waiting to STOP\n"); } else { spin_unlock_irqrestore(&unicam_dev->lock, flags); } usleep_range(50, 60); /*TODO: Need to double-check with ASIC team*/ spin_lock_irqsave(&unicam_dev->lock, flags); /* disable frame interrupts */ cslCamFrame.int_enable = CSL_CAM_INT_DISABLE; cslCamFrame.int_line_count = 0; cslCamFrame.capture_mode = UNICAM_CAPTURE_MODE; cslCamFrame.capture_size = 0; if (csl_cam_set_frame_control(unicam_dev->cslCamHandle, &cslCamFrame)) { dev_err(unicam_dev->dev, "csl_cam_set_frame_control(): FAILED\n"); ret = -1; } /* disable receiver */ if (csl_cam_rx_stop(unicam_dev->cslCamHandle)) { dev_err(unicam_dev->dev, "csl_cam_rx_stop(): FAILED\n"); ret = -1; } if (csl_cam_close(unicam_dev->cslCamHandle)) { dev_err(unicam_dev->dev, "cals_cam_exit(): FAILED\n"); ret = -1; } if (csl_cam_exit()) { dev_err(unicam_dev->dev, "csl_cam_exit(): FAILED\n"); ret = -1; } unicam_dev->active = NULL; unicam_dev->streaming = 0; out: dprintk("-exit"); spin_unlock_irqrestore(&unicam_dev->lock, flags); up(&unicam_dev->stop_processing_sem); /* Stopping stream after stopping unicam */ ret = v4l2_subdev_call(sd, video, s_stream, 0); if (ret < 0 && ret != -ENOIOCTLCMD) { dev_err(unicam_dev->dev, "failed to stop sensor streaming\n"); ret = -1; } return ret; }
int unicam_videobuf_start_streaming(struct vb2_queue *q, unsigned int count) { struct soc_camera_device *icd = soc_camera_from_vb2q(q); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct unicam_camera_dev *unicam_dev = ici->priv; struct v4l2_subdev_sensor_interface_parms if_params; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); int ret; int thumb; unsigned long flags; CSL_CAM_INTF_CFG_st_t csl_cam_intf_cfg_st; CSL_CAM_LANE_CONTROL_st_t cslCamLaneCtrl_st; CSL_CAM_PIPELINE_st_t cslCamPipeline; CSL_CAM_IMAGE_ID_st_t cslCamImageCtrl; CSL_CAM_DATA_st_t cslCamDataCtrl; CSL_CAM_FRAME_st_t cslCamFrame; dprintk("-enter"); iprintk("enabling csi"); spin_lock_irqsave(&unicam_dev->lock, flags); unicam_dev->stopping = false; spin_unlock_irqrestore(&unicam_dev->lock, flags); if (csl_cam_init()) { dev_err(unicam_dev->dev, "error initializing csl camera\n"); return -1; } ret = v4l2_subdev_call(sd, video, s_stream, 1); if (ret < 0 && ret != -ENOIOCTLCMD) { dev_err(unicam_dev->dev, "error on s_stream(%d)\n", ret); spin_lock_irqsave(&unicam_dev->lock, flags); unicam_dev->active = NULL; unicam_dev->stopping = true; spin_unlock_irqrestore(&unicam_dev->lock, flags); if (csl_cam_exit()) dev_err(unicam_dev->dev, "csl_cam_exit(): FAILED\n"); return ret; } /* get the sensor interface information */ ret = v4l2_subdev_call(sd, sensor, g_interface_parms, &if_params); if (ret < 0) { dev_err(unicam_dev->dev, "error on g_inferface_params(%d)\n", ret); return ret; } unicam_dev->if_params = if_params; /* set camera interface parameters */ memset(&csl_cam_intf_cfg_st, 0, sizeof(CSL_CAM_INTF_CFG_st_t)); /* we only support serial and csi2 sensor */ if ((unicam_dev->if_params.if_type == V4L2_SUBDEV_SENSOR_SERIAL) && (unicam_dev->if_params.if_mode == V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI2)) { csl_cam_intf_cfg_st.intf = CSL_CAM_INTF_CSI; } else if ((unicam_dev->if_params.if_type == V4L2_SUBDEV_SENSOR_SERIAL) && (unicam_dev->if_params.if_mode == V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI1)) { csl_cam_intf_cfg_st.intf = CSL_CAM_INTF_CCP; } else { dev_err(unicam_dev->dev, "CSI2 iface only supported,requested iface %d mode=%d\n", unicam_dev->if_params.if_type, unicam_dev->if_params.if_mode); return -EINVAL; } if (unicam_dev->if_params.parms.serial.channel == 0) csl_cam_intf_cfg_st.afe_port = CSL_CAM_PORT_AFE_0; else if (unicam_dev->if_params.parms.serial.channel == 1) csl_cam_intf_cfg_st.afe_port = CSL_CAM_PORT_AFE_1; else { dev_err(unicam_dev->dev, "receiver only supports two channels, request channel=%d\n", unicam_dev->if_params.parms.serial.channel); return -EINVAL; } csl_cam_intf_cfg_st.frame_time_out = 1000; /* open camera interface */ csl_cam_intf_cfg_st.p_cpi_intf_st = NULL; if ((unicam_dev->if_params.if_type == V4L2_SUBDEV_SENSOR_SERIAL) && (unicam_dev->if_params.if_mode == V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI2)) { if (unicam_dev->if_params.parms.serial.lanes == 1) csl_cam_intf_cfg_st.input_mode = CSL_CAM_INPUT_SINGLE_LANE; else if (unicam_dev->if_params.parms.serial.lanes == 2) csl_cam_intf_cfg_st.input_mode = CSL_CAM_INPUT_DUAL_LANE; else { dev_err(unicam_dev->dev, "receiver only supports max 2 lanes, requested lanes(%d)\n", unicam_dev->if_params.parms.serial.lanes); return -EINVAL; } } else { csl_cam_intf_cfg_st.input_mode = CSL_CAM_INPUT_MODE_DATA_CLOCK; } if (csl_cam_open(&csl_cam_intf_cfg_st, &unicam_dev->cslCamHandle)) { dev_err(unicam_dev->dev, "%s: csl_cam_open(): ERROR\n", __func__); return -1; } /* set data lane timing */ cslCamLaneCtrl_st.lane_select = CSL_CAM_DATA_LANE_0; cslCamLaneCtrl_st.lane_control = CSL_CAM_LANE_HS_TERM_TIME; cslCamLaneCtrl_st.param = unicam_dev->if_params.parms.serial.hs_term_time; dprintk("hs_term_time is set to = %d\n", cslCamLaneCtrl_st.param); if (csl_cam_set_lane_control (unicam_dev->cslCamHandle, &cslCamLaneCtrl_st)) { dev_err(unicam_dev->dev, "csl_cam_set_lane_control(): FAILED\n"); return -1; } if (unicam_dev->if_params.parms.serial.hs_settle_time != 0) { cslCamLaneCtrl_st.lane_select = CSL_CAM_DATA_LANE_0; cslCamLaneCtrl_st.lane_control = CSL_CAM_LANE_HS_SETTLE_TIME; cslCamLaneCtrl_st.param = unicam_dev->if_params.parms.serial.hs_settle_time; dprintk("hs_settle_time is set to = %d\n", cslCamLaneCtrl_st.param); if (csl_cam_set_lane_control (unicam_dev->cslCamHandle, &cslCamLaneCtrl_st)) { dev_err(unicam_dev->dev, "csl_cam_set_lane_control(): FAILED\n"); return -1; } } /* pipelince decode */ cslCamPipeline.decode = CSL_CAM_DEC_NONE; cslCamPipeline.unpack = CSL_CAM_PIXEL_NONE; cslCamPipeline.pack = CSL_CAM_PIXEL_NONE; cslCamPipeline.dec_adv_predictor = FALSE; cslCamPipeline.encode = CSL_CAM_ENC_NONE; cslCamPipeline.enc_adv_predictor = FALSE; cslCamPipeline.encode_blk_size = 0x0000; /* set pipeline */ if (csl_cam_set_pipeline_control (unicam_dev->cslCamHandle, &cslCamPipeline)) { dev_err(unicam_dev->dev, "csl_cam_set_pipeline_control(): FAILE\n"); return -1; } /* set image identifier (CSI mode only) */ memset(&cslCamImageCtrl, 0, sizeof(CSL_CAM_IMAGE_ID_st_t)); /* if thumbnail is supported we expect * thumbnail to be in image ptr format of thumbnails is yuv422 * format is checked in try format. * in case where thumbnail is not supported we get jpeg * image in data pointer. so we set the id as 0 */ thumb = 0; ret = v4l2_subdev_call(sd, core, ioctl, VIDIOC_THUMB_SUPPORTED, (void *)&thumb); if (ret < 0) dev_warn(unicam_dev->dev, "sensor returns error(%d) for VIDIOC_THUMB_SUPPORTED\n", ret); if ((icd->current_fmt->code == V4L2_MBUS_FMT_JPEG_1X8) && (thumb == 0)) cslCamImageCtrl.image_data_id0 = 0x0; /* thumbnail not supported */ else cslCamImageCtrl.image_data_id0 = 0x1E; if (unicam_dev->if_params.if_mode == V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI1) cslCamImageCtrl.image_data_id0 = 0x0; /* CCP2 channel ID 0 */ if (csl_cam_set_image_type_control (unicam_dev->cslCamHandle, &cslCamImageCtrl)) { dev_err(unicam_dev->dev, "csl_cam_set_image_type_control(): FAILED\n"); return -1; } /* set data capture */ cslCamDataCtrl.int_enable = (CSL_CAM_INTERRUPT_t) (CSL_CAM_INT_DISABLE); if (unicam_dev->if_params.if_mode == V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI2) { cslCamDataCtrl.line_count = 2; cslCamDataCtrl.fsp_decode_enable = FALSE; } else { cslCamDataCtrl.line_count = 0; cslCamDataCtrl.fsp_decode_enable = TRUE; } cslCamDataCtrl.data_id = 0x00; cslCamDataCtrl.data_size = CSL_CAM_PIXEL_8BIT; if (csl_cam_set_data_type_control (unicam_dev->cslCamHandle, &cslCamDataCtrl)) { dev_err(unicam_dev->dev, "csl_cam_set_data_type_control(): FAILED\n"); return -1; } /* start receiver */ if (csl_cam_rx_start(unicam_dev->cslCamHandle)) { dev_err(unicam_dev->dev, "csl_cam_rx_start(): FAILED\n"); return -1; } /* Enabling sensor after enabling unicam */ /* ret = v4l2_subdev_call(sd, video, s_stream, 1); if (ret < 0 && ret != -ENOIOCTLCMD) { dev_err(unicam_dev->dev, "error on s_stream(%d)\n", ret); return ret; } */ if (unicam_dev->if_params.if_mode == V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI1) { cslCamFrame.int_enable = CSL_CAM_INT_LINE_COUNT; /* CSL_CAM_INT_FRAME_END | CSL_CAM_INT_FRAME_START; //CSL_CAM_INT_LINE_COUNT; cslCamFrame.int_line_count = (unicam_dev->icd->user_height - 1);*/ cslCamFrame.int_line_count = (unicam_dev->icd->user_height); cslCamFrame.capture_mode = CSL_CAM_CAPTURE_MODE_NORMAL; /* CSL_CAM_CAPTURE_MODE_NORMAL */ if (csl_cam_set_frame_control( unicam_dev->cslCamHandle, &cslCamFrame)) { dev_err(unicam_dev->dev, "csl_cam_set_frame_control(): FAILED\n"); return -1; } } /* Configure HW if buffer is queued ahead of streamon */ spin_lock_irqsave(&unicam_dev->lock, flags); if(unicam_dev->active){ unicam_camera_update_buf(unicam_dev); if (unicam_dev->if_params.if_mode == V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI2) unicam_camera_capture(unicam_dev); } unicam_dev->streaming = 1; spin_unlock_irqrestore(&unicam_dev->lock, flags); csl_cam_register_display(unicam_dev->cslCamHandle); dprintk("-exit"); return 0; }