static int fimc_isp_subdev_s_stream(struct v4l2_subdev *sd, int on) { struct fimc_isp *isp = v4l2_get_subdevdata(sd); struct fimc_is *is = fimc_isp_to_is(isp); int ret; isp_dbg(1, sd, "%s: on: %d\n", __func__, on); if (!test_bit(IS_ST_INIT_DONE, &is->state)) return -EBUSY; fimc_is_mem_barrier(); if (on) { if (__get_pending_param_count(is)) { ret = fimc_is_itf_s_param(is, true); if (ret < 0) return ret; } isp_dbg(1, sd, "changing mode to %d\n", is->config_index); ret = fimc_is_itf_mode_change(is); if (ret) return -EINVAL; clear_bit(IS_ST_STREAM_ON, &is->state); fimc_is_hw_stream_on(is); ret = fimc_is_wait_event(is, IS_ST_STREAM_ON, 1, FIMC_IS_CONFIG_TIMEOUT); if (ret < 0) { v4l2_err(sd, "stream on timeout\n"); return ret; } } else { clear_bit(IS_ST_STREAM_OFF, &is->state); fimc_is_hw_stream_off(is); ret = fimc_is_wait_event(is, IS_ST_STREAM_OFF, 1, FIMC_IS_CONFIG_TIMEOUT); if (ret < 0) { v4l2_err(sd, "stream off timeout\n"); return ret; } is->setfile.sub_index = 0; } return 0; }
int fimc_is_hw_initialize(struct fimc_is *is) { const int config_ids[] = { IS_SC_PREVIEW_STILL, IS_SC_PREVIEW_VIDEO, IS_SC_CAPTURE_STILL, IS_SC_CAPTURE_VIDEO }; struct device *dev = &is->pdev->dev; u32 prev_id; int i, ret; /* Sensor initialization. */ ret = fimc_is_hw_open_sensor(is, is->sensor); if (ret < 0) return ret; /* Get the setfile address. */ fimc_is_hw_get_setfile_addr(is); ret = fimc_is_wait_event(is, IS_ST_SETFILE_LOADED, 1, FIMC_IS_CONFIG_TIMEOUT); if (ret < 0) { dev_err(dev, "get setfile address timed out\n"); return ret; } pr_debug("setfile.base: %#x\n", is->setfile.base); /* Load the setfile. */ fimc_is_load_setfile(is, FIMC_IS_SETFILE_6A3); clear_bit(IS_ST_SETFILE_LOADED, &is->state); fimc_is_hw_load_setfile(is); ret = fimc_is_wait_event(is, IS_ST_SETFILE_LOADED, 1, FIMC_IS_CONFIG_TIMEOUT); if (ret < 0) { dev_err(dev, "loading setfile timed out\n"); return ret; } pr_debug("setfile: base: %#x, size: %d\n", is->setfile.base, is->setfile.size); pr_info("FIMC-IS Setfile info: %s\n", is->fw.setfile_info); /* Check magic number. */ if (is->is_p_region->shared[MAX_SHARED_COUNT - 1] != FIMC_IS_MAGIC_NUMBER) { dev_err(dev, "magic number error!\n"); return -EIO; } pr_debug("shared region: %#x, parameter region: %#x\n", is->memory.paddr + FIMC_IS_SHARED_REGION_OFFSET, is->is_dma_p_region); is->setfile.sub_index = 0; /* Stream off. */ fimc_is_hw_stream_off(is); ret = fimc_is_wait_event(is, IS_ST_STREAM_OFF, 1, FIMC_IS_CONFIG_TIMEOUT); if (ret < 0) { dev_err(dev, "stream off timeout\n"); return ret; } /* Preserve previous mode. */ prev_id = is->config_index; /* Set initial parameter values. */ for (i = 0; i < ARRAY_SIZE(config_ids); i++) { is->config_index = config_ids[i]; fimc_is_set_initial_params(is); ret = fimc_is_itf_s_param(is, true); if (ret < 0) { is->config_index = prev_id; return ret; } } is->config_index = prev_id; set_bit(IS_ST_INIT_DONE, &is->state); dev_info(dev, "initialization sequence completed (%d)\n", is->config_index); return 0; }