Esempio n. 1
0
static int32_t msm_ois_i2c_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
	int rc = 0;
	struct msm_ois_ctrl_t *ois_ctrl_t = NULL;
	struct msm_ois_vreg *vreg_cfg;
	bool check_use_gpios;

	CDBG_I("Enter\n");

	if (client == NULL) {
		pr_err("msm_ois_i2c_probe: client is null\n");
		rc = -EINVAL;
		goto probe_failure;
	}

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("i2c_check_functionality failed\n");
		goto probe_failure;
	}

	if (!client->dev.of_node) {
		ois_ctrl_t = (struct msm_ois_ctrl_t *)(id->driver_data);
	} else {
		ois_ctrl_t = kzalloc(sizeof(struct msm_ois_ctrl_t),
			GFP_KERNEL);
		if (!ois_ctrl_t) {
			pr_err("%s:%d no memory\n", __func__, __LINE__);
			return -ENOMEM;
		}
		if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
			pr_err("i2c_check_functionality failed\n");
			goto probe_failure;
		}

		CDBG("client = 0x%p\n",  client);

		rc = of_property_read_u32(client->dev.of_node, "cell-index",
			&ois_ctrl_t->subdev_id);
		CDBG("cell-index %d, rc %d\n", ois_ctrl_t->subdev_id, rc);
		ois_ctrl_t->cam_name = ois_ctrl_t->subdev_id;
		if (rc < 0) {
			pr_err("failed rc %d\n", rc);
			kfree(ois_ctrl_t);//prevent
			return rc;
		}
		check_use_gpios = of_property_read_bool(client->dev.of_node, "unuse-gpios");
		CDBG("%s: check unuse-gpio flag(%d)\n",
			__FUNCTION__, check_use_gpios);
		if (!check_use_gpios) {
			rc = msm_ois_get_gpio_data(ois_ctrl_t,
				client->dev.of_node);
		}
	}

	if (of_find_property(client->dev.of_node,
			"qcom,cam-vreg-name", NULL)) {
		vreg_cfg = &ois_ctrl_t->vreg_cfg;
		rc = msm_camera_get_dt_vreg_data(client->dev.of_node,
			&vreg_cfg->cam_vreg, &vreg_cfg->num_vreg);
		if (rc < 0) {
			kfree(ois_ctrl_t);
			pr_err("failed rc %d\n", rc);
			return rc;
		}
	}

	ois_ctrl_t->ois_v4l2_subdev_ops = &msm_ois_subdev_ops;
	ois_ctrl_t->ois_mutex = &msm_ois_mutex;
	ois_ctrl_t->i2c_driver = &msm_ois_i2c_driver;

	CDBG("client = %x\n", (unsigned int) client);
	ois_ctrl_t->i2c_client.client = client;
	ois_ctrl_t->i2c_client.addr_type = MSM_CAMERA_I2C_WORD_ADDR;
	/* Set device type as I2C */
	ois_ctrl_t->ois_device_type = MSM_CAMERA_I2C_DEVICE;
	ois_ctrl_t->i2c_client.i2c_func_tbl = &msm_sensor_qup_func_tbl;
	ois_ctrl_t->ois_v4l2_subdev_ops = &msm_ois_subdev_ops;
	ois_ctrl_t->ois_mutex = &msm_ois_mutex;

	ois_ctrl_t->cam_name = ois_ctrl_t->subdev_id;
	CDBG("ois_ctrl_t->cam_name: %d", ois_ctrl_t->cam_name);
	/* Assign name for sub device */
	snprintf(ois_ctrl_t->msm_sd.sd.name, sizeof(ois_ctrl_t->msm_sd.sd.name),
		"%s", ois_ctrl_t->i2c_driver->driver.name);

	/* Initialize sub device */
	v4l2_i2c_subdev_init(&ois_ctrl_t->msm_sd.sd,
		ois_ctrl_t->i2c_client.client,
		ois_ctrl_t->ois_v4l2_subdev_ops);
	v4l2_set_subdevdata(&ois_ctrl_t->msm_sd.sd, ois_ctrl_t);
	ois_ctrl_t->msm_sd.sd.internal_ops = &msm_ois_internal_ops;
	ois_ctrl_t->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	media_entity_init(&ois_ctrl_t->msm_sd.sd.entity, 0, NULL, 0);
	ois_ctrl_t->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	ois_ctrl_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_OIS;
	ois_ctrl_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0xB;
	msm_sd_register(&ois_ctrl_t->msm_sd);
	//g_ois_i2c_client.client = ois_ctrl_t->i2c_client.client;

	CDBG("Succeded Exit\n");
	return rc;
probe_failure:
	if (ois_ctrl_t)
		kfree(ois_ctrl_t);
	return rc;
}
static int msm_eeprom_i2c_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	int rc = 0;
	struct msm_eeprom_ctrl_t *e_ctrl = NULL;
	struct msm_camera_power_ctrl_t *power_info = NULL;
	CDBG("%s E\n", __func__);

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s i2c_check_functionality failed\n", __func__);
		goto probe_failure;
	}

	e_ctrl = kzalloc(sizeof(*e_ctrl), GFP_KERNEL);
	if (!e_ctrl) {
		pr_err("%s:%d kzalloc failed\n", __func__, __LINE__);
		return -ENOMEM;
	}
	e_ctrl->eeprom_v4l2_subdev_ops = &msm_eeprom_subdev_ops;
	e_ctrl->eeprom_mutex = &msm_eeprom_mutex;
	CDBG("%s client = %x\n", __func__, (unsigned int)client);
	e_ctrl->eboard_info = (struct msm_eeprom_board_info *)(id->driver_data);
	if (!e_ctrl->eboard_info) {
		pr_err("%s:%d board info NULL\n", __func__, __LINE__);
		rc = -EINVAL;
		goto ectrl_free;
	}
	power_info = &e_ctrl->eboard_info->power_info;
	e_ctrl->i2c_client.client = client;

	/* Set device type as I2C */
	e_ctrl->eeprom_device_type = MSM_CAMERA_I2C_DEVICE;
	e_ctrl->i2c_client.i2c_func_tbl = &msm_eeprom_qup_func_tbl;

	if (e_ctrl->eboard_info->i2c_slaveaddr != 0)
		e_ctrl->i2c_client.client->addr =
					e_ctrl->eboard_info->i2c_slaveaddr;
	power_info->clk_info = cam_8960_clk_info;
	power_info->clk_info_size = ARRAY_SIZE(cam_8960_clk_info);
	power_info->dev = &client->dev;

	/* Initialize sub device */
	v4l2_i2c_subdev_init(&e_ctrl->msm_sd.sd,
		e_ctrl->i2c_client.client,
		e_ctrl->eeprom_v4l2_subdev_ops);
	v4l2_set_subdevdata(&e_ctrl->msm_sd.sd, e_ctrl);
	e_ctrl->msm_sd.sd.internal_ops = &msm_eeprom_internal_ops;
	e_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	media_entity_init(&e_ctrl->msm_sd.sd.entity, 0, NULL, 0);
	e_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	e_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_EEPROM;
	msm_sd_register(&e_ctrl->msm_sd);
	CDBG("%s success result=%d X\n", __func__, rc);
	return rc;

ectrl_free:
	kfree(e_ctrl);
probe_failure:
	pr_err("%s failed! rc = %d\n", __func__, rc);
	return rc;
}
static int __devinit ispif_probe(struct platform_device *pdev)
{
	int rc;
	struct ispif_device *ispif;

	ispif = kzalloc(sizeof(struct ispif_device), GFP_KERNEL);
	if (!ispif) {
		pr_err("%s: no enough memory\n", __func__);
		return -ENOMEM;
	}

	v4l2_subdev_init(&ispif->msm_sd.sd, &msm_ispif_subdev_ops);
	ispif->msm_sd.sd.internal_ops = &msm_ispif_internal_ops;
	ispif->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;

	snprintf(ispif->msm_sd.sd.name,
		ARRAY_SIZE(ispif->msm_sd.sd.name), MSM_ISPIF_DRV_NAME);
	v4l2_set_subdevdata(&ispif->msm_sd.sd, ispif);

	platform_set_drvdata(pdev, &ispif->msm_sd.sd);
	mutex_init(&ispif->mutex);

	media_entity_init(&ispif->msm_sd.sd.entity, 0, NULL, 0);
	ispif->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	ispif->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ISPIF;
	ispif->msm_sd.sd.entity.name = pdev->name;
	ispif->msm_sd.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x1;
	rc = msm_sd_register(&ispif->msm_sd);
	if (rc) {
		pr_err("%s: msm_sd_register error = %d\n", __func__, rc);
		goto error_sd_register;
	}


	if (pdev->dev.of_node) {
		of_property_read_u32((&pdev->dev)->of_node,
		"cell-index", &pdev->id);
		rc = of_property_read_u32((&pdev->dev)->of_node,
		"qcom,num-isps", &ispif->hw_num_isps);
		if (rc)
			/* backward compatibility */
			ispif->hw_num_isps = 1;
		/* not an error condition */
		rc = 0;
	}

	ispif->mem = platform_get_resource_byname(pdev,
		IORESOURCE_MEM, "ispif");
	if (!ispif->mem) {
		pr_err("%s: no mem resource?\n", __func__);
		rc = -ENODEV;
		goto error;
	}
	ispif->irq = platform_get_resource_byname(pdev,
		IORESOURCE_IRQ, "ispif");
	if (!ispif->irq) {
		pr_err("%s: no irq resource?\n", __func__);
		rc = -ENODEV;
		goto error;
	}
	ispif->io = request_mem_region(ispif->mem->start,
		resource_size(ispif->mem), pdev->name);
	if (!ispif->io) {
		pr_err("%s: no valid mem region\n", __func__);
		rc = -EBUSY;
		goto error;
	}
	ispif->clk_mux_mem = platform_get_resource_byname(pdev,
		IORESOURCE_MEM, "csi_clk_mux");
	if (ispif->clk_mux_mem) {
		ispif->clk_mux_io = request_mem_region(
			ispif->clk_mux_mem->start,
			resource_size(ispif->clk_mux_mem),
			ispif->clk_mux_mem->name);
		if (!ispif->clk_mux_io)
			pr_err("%s: no valid csi_mux region\n", __func__);
	}

	ispif->pdev = pdev;
	ispif->ispif_state = ISPIF_POWER_DOWN;
	ispif->open_cnt = 0;

	return 0;

error:
	msm_sd_unregister(&ispif->msm_sd);
error_sd_register:
	mutex_destroy(&ispif->mutex);
	kfree(ispif);
	return rc;
}
static int mt9m032_setup_pll(struct mt9m032 *sensor)
{
	static const struct aptina_pll_limits limits = {
		.ext_clock_min = 8000000,
		.ext_clock_max = 16500000,
		.int_clock_min = 2000000,
		.int_clock_max = 24000000,
		.out_clock_min = 322000000,
		.out_clock_max = 693000000,
		.pix_clock_max = 99000000,
		.n_min = 1,
		.n_max = 64,
		.m_min = 16,
		.m_max = 255,
		.p1_min = 1,
		.p1_max = 128,
	};

	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
	struct mt9m032_platform_data *pdata = sensor->pdata;
	struct aptina_pll pll;
	int ret;

	pll.ext_clock = pdata->ext_clock;
	pll.pix_clock = pdata->pix_clock;

	ret = aptina_pll_calculate(&client->dev, &limits, &pll);
	if (ret < 0)
		return ret;

	sensor->pix_clock = pdata->pix_clock;

	ret = mt9m032_write(client, MT9M032_PLL_CONFIG1,
			    (pll.m << MT9M032_PLL_CONFIG1_MUL_SHIFT)
			    | (pll.p1 - 1));
	if (!ret)
		ret = mt9m032_write(client, MT9P031_PLL_CONFIG2, pll.n - 1);
	if (!ret)
		ret = mt9m032_write(client, MT9P031_PLL_CONTROL,
				    MT9P031_PLL_CONTROL_PWRON |
				    MT9P031_PLL_CONTROL_USEPLL);
	if (!ret)		/* more reserved, Continuous, Master Mode */
		ret = mt9m032_write(client, MT9M032_READ_MODE1, 0x8006);
	if (!ret)		/* Set 14-bit mode, select 7 divider */
		ret = mt9m032_write(client, MT9M032_FORMATTER1, 0x111e);

	return ret;
}

/* -----------------------------------------------------------------------------
 * Subdev pad operations
 */

static int mt9m032_enum_mbus_code(struct v4l2_subdev *subdev,
				  struct v4l2_subdev_fh *fh,
				  struct v4l2_subdev_mbus_code_enum *code)
{
	if (code->index != 0)
		return -EINVAL;

	code->code = V4L2_MBUS_FMT_Y8_1X8;
	return 0;
}

static int mt9m032_enum_frame_size(struct v4l2_subdev *subdev,
				   struct v4l2_subdev_fh *fh,
				   struct v4l2_subdev_frame_size_enum *fse)
{
	if (fse->index != 0 || fse->code != V4L2_MBUS_FMT_Y8_1X8)
		return -EINVAL;

	fse->min_width = MT9M032_COLUMN_SIZE_DEF;
	fse->max_width = MT9M032_COLUMN_SIZE_DEF;
	fse->min_height = MT9M032_ROW_SIZE_DEF;
	fse->max_height = MT9M032_ROW_SIZE_DEF;

	return 0;
}

/**
 * __mt9m032_get_pad_crop() - get crop rect
 * @sensor: pointer to the sensor struct
 * @fh: file handle for getting the try crop rect from
 * @which: select try or active crop rect
 *
 * Returns a pointer the current active or fh relative try crop rect
 */
static struct v4l2_rect *
__mt9m032_get_pad_crop(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh,
		       enum v4l2_subdev_format_whence which)
{
	switch (which) {
	case V4L2_SUBDEV_FORMAT_TRY:
		return v4l2_subdev_get_try_crop(fh, 0);
	case V4L2_SUBDEV_FORMAT_ACTIVE:
		return &sensor->crop;
	default:
		return NULL;
	}
}

/**
 * __mt9m032_get_pad_format() - get format
 * @sensor: pointer to the sensor struct
 * @fh: file handle for getting the try format from
 * @which: select try or active format
 *
 * Returns a pointer the current active or fh relative try format
 */
static struct v4l2_mbus_framefmt *
__mt9m032_get_pad_format(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh,
			 enum v4l2_subdev_format_whence which)
{
	switch (which) {
	case V4L2_SUBDEV_FORMAT_TRY:
		return v4l2_subdev_get_try_format(fh, 0);
	case V4L2_SUBDEV_FORMAT_ACTIVE:
		return &sensor->format;
	default:
		return NULL;
	}
}

static int mt9m032_get_pad_format(struct v4l2_subdev *subdev,
				  struct v4l2_subdev_fh *fh,
				  struct v4l2_subdev_format *fmt)
{
	struct mt9m032 *sensor = to_mt9m032(subdev);

	mutex_lock(&sensor->lock);
	fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which);
	mutex_unlock(&sensor->lock);

	return 0;
}

static int mt9m032_set_pad_format(struct v4l2_subdev *subdev,
				  struct v4l2_subdev_fh *fh,
				  struct v4l2_subdev_format *fmt)
{
	struct mt9m032 *sensor = to_mt9m032(subdev);
	int ret;

	mutex_lock(&sensor->lock);

	if (sensor->streaming && fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
		ret = -EBUSY;
		goto done;
	}

	/* Scaling is not supported, the format is thus fixed. */
	fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which);
	ret = 0;

done:
	mutex_unlock(&sensor->lock);
	return ret;
}

static int mt9m032_get_pad_crop(struct v4l2_subdev *subdev,
				struct v4l2_subdev_fh *fh,
				struct v4l2_subdev_crop *crop)
{
	struct mt9m032 *sensor = to_mt9m032(subdev);

	mutex_lock(&sensor->lock);
	crop->rect = *__mt9m032_get_pad_crop(sensor, fh, crop->which);
	mutex_unlock(&sensor->lock);

	return 0;
}

static int mt9m032_set_pad_crop(struct v4l2_subdev *subdev,
				struct v4l2_subdev_fh *fh,
				struct v4l2_subdev_crop *crop)
{
	struct mt9m032 *sensor = to_mt9m032(subdev);
	struct v4l2_mbus_framefmt *format;
	struct v4l2_rect *__crop;
	struct v4l2_rect rect;
	int ret = 0;

	mutex_lock(&sensor->lock);

	if (sensor->streaming && crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
		ret = -EBUSY;
		goto done;
	}

	/* Clamp the crop rectangle boundaries and align them to a multiple of 2
	 * pixels to ensure a GRBG Bayer pattern.
	 */
	rect.left = clamp(ALIGN(crop->rect.left, 2), MT9M032_COLUMN_START_MIN,
			  MT9M032_COLUMN_START_MAX);
	rect.top = clamp(ALIGN(crop->rect.top, 2), MT9M032_ROW_START_MIN,
			 MT9M032_ROW_START_MAX);
	rect.width = clamp(ALIGN(crop->rect.width, 2), MT9M032_COLUMN_SIZE_MIN,
			   MT9M032_COLUMN_SIZE_MAX);
	rect.height = clamp(ALIGN(crop->rect.height, 2), MT9M032_ROW_SIZE_MIN,
			    MT9M032_ROW_SIZE_MAX);

	rect.width = min(rect.width, MT9M032_PIXEL_ARRAY_WIDTH - rect.left);
	rect.height = min(rect.height, MT9M032_PIXEL_ARRAY_HEIGHT - rect.top);

	__crop = __mt9m032_get_pad_crop(sensor, fh, crop->which);

	if (rect.width != __crop->width || rect.height != __crop->height) {
		/* Reset the output image size if the crop rectangle size has
		 * been modified.
		 */
		format = __mt9m032_get_pad_format(sensor, fh, crop->which);
		format->width = rect.width;
		format->height = rect.height;
	}

	*__crop = rect;
	crop->rect = rect;

	if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE)
		ret = mt9m032_update_geom_timing(sensor);

done:
	mutex_unlock(&sensor->lock);
	return ret;
}

static int mt9m032_get_frame_interval(struct v4l2_subdev *subdev,
				      struct v4l2_subdev_frame_interval *fi)
{
	struct mt9m032 *sensor = to_mt9m032(subdev);

	mutex_lock(&sensor->lock);
	memset(fi, 0, sizeof(*fi));
	fi->interval = sensor->frame_interval;
	mutex_unlock(&sensor->lock);

	return 0;
}

static int mt9m032_set_frame_interval(struct v4l2_subdev *subdev,
				      struct v4l2_subdev_frame_interval *fi)
{
	struct mt9m032 *sensor = to_mt9m032(subdev);
	int ret;

	mutex_lock(&sensor->lock);

	if (sensor->streaming) {
		ret = -EBUSY;
		goto done;
	}

	/* Avoid divisions by 0. */
	if (fi->interval.denominator == 0)
		fi->interval.denominator = 1;

	ret = mt9m032_update_timing(sensor, &fi->interval);
	if (!ret)
		sensor->frame_interval = fi->interval;

done:
	mutex_unlock(&sensor->lock);
	return ret;
}

static int mt9m032_s_stream(struct v4l2_subdev *subdev, int streaming)
{
	struct mt9m032 *sensor = to_mt9m032(subdev);
	int ret;

	mutex_lock(&sensor->lock);
	ret = update_formatter2(sensor, streaming);
	if (!ret)
		sensor->streaming = streaming;
	mutex_unlock(&sensor->lock);

	return ret;
}

/* -----------------------------------------------------------------------------
 * V4L2 subdev core operations
 */

#ifdef CONFIG_VIDEO_ADV_DEBUG
static int mt9m032_g_register(struct v4l2_subdev *sd,
			      struct v4l2_dbg_register *reg)
{
	struct mt9m032 *sensor = to_mt9m032(sd);
	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
	int val;

	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
		return -EINVAL;
	if (reg->match.addr != client->addr)
		return -ENODEV;

	val = mt9m032_read(client, reg->reg);
	if (val < 0)
		return -EIO;

	reg->size = 2;
	reg->val = val;

	return 0;
}

static int mt9m032_s_register(struct v4l2_subdev *sd,
			      struct v4l2_dbg_register *reg)
{
	struct mt9m032 *sensor = to_mt9m032(sd);
	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);

	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
		return -EINVAL;

	if (reg->match.addr != client->addr)
		return -ENODEV;

	return mt9m032_write(client, reg->reg, reg->val);
}
#endif

/* -----------------------------------------------------------------------------
 * V4L2 subdev control operations
 */

static int update_read_mode2(struct mt9m032 *sensor, bool vflip, bool hflip)
{
	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
	int reg_val = (vflip << MT9M032_READ_MODE2_VFLIP_SHIFT)
		    | (hflip << MT9M032_READ_MODE2_HFLIP_SHIFT)
		    | MT9M032_READ_MODE2_ROW_BLC
		    | 0x0007;

	return mt9m032_write(client, MT9M032_READ_MODE2, reg_val);
}

static int mt9m032_set_gain(struct mt9m032 *sensor, s32 val)
{
	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
	int digital_gain_val;	/* in 1/8th (0..127) */
	int analog_mul;		/* 0 or 1 */
	int analog_gain_val;	/* in 1/16th. (0..63) */
	u16 reg_val;

	digital_gain_val = 51; /* from setup example */

	if (val < 63) {
		analog_mul = 0;
		analog_gain_val = val;
	} else {
		analog_mul = 1;
		analog_gain_val = val / 2;
	}

	/* a_gain = (1 + analog_mul) + (analog_gain_val + 1) / 16 */
	/* overall_gain = a_gain * (1 + digital_gain_val / 8) */

	reg_val = ((digital_gain_val & MT9M032_GAIN_DIGITAL_MASK)
		   << MT9M032_GAIN_DIGITAL_SHIFT)
		| ((analog_mul & 1) << MT9M032_GAIN_AMUL_SHIFT)
		| (analog_gain_val & MT9M032_GAIN_ANALOG_MASK);

	return mt9m032_write(client, MT9M032_GAIN_ALL, reg_val);
}

static int mt9m032_try_ctrl(struct v4l2_ctrl *ctrl)
{
	if (ctrl->id == V4L2_CID_GAIN && ctrl->val >= 63) {
		/* round because of multiplier used for values >= 63 */
		ctrl->val &= ~1;
	}

	return 0;
}

static int mt9m032_set_ctrl(struct v4l2_ctrl *ctrl)
{
	struct mt9m032 *sensor =
		container_of(ctrl->handler, struct mt9m032, ctrls);
	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
	int ret;

	switch (ctrl->id) {
	case V4L2_CID_GAIN:
		return mt9m032_set_gain(sensor, ctrl->val);

	case V4L2_CID_HFLIP:
	/* case V4L2_CID_VFLIP: -- In the same cluster */
		return update_read_mode2(sensor, sensor->vflip->val,
					 sensor->hflip->val);

	case V4L2_CID_EXPOSURE:
		ret = mt9m032_write(client, MT9M032_SHUTTER_WIDTH_HIGH,
				    (ctrl->val >> 16) & 0xffff);
		if (ret < 0)
			return ret;

		return mt9m032_write(client, MT9M032_SHUTTER_WIDTH_LOW,
				     ctrl->val & 0xffff);
	}

	return 0;
}

static struct v4l2_ctrl_ops mt9m032_ctrl_ops = {
	.s_ctrl = mt9m032_set_ctrl,
	.try_ctrl = mt9m032_try_ctrl,
};

/* -------------------------------------------------------------------------- */

static const struct v4l2_subdev_core_ops mt9m032_core_ops = {
#ifdef CONFIG_VIDEO_ADV_DEBUG
	.g_register = mt9m032_g_register,
	.s_register = mt9m032_s_register,
#endif
};

static const struct v4l2_subdev_video_ops mt9m032_video_ops = {
	.s_stream = mt9m032_s_stream,
	.g_frame_interval = mt9m032_get_frame_interval,
	.s_frame_interval = mt9m032_set_frame_interval,
};

static const struct v4l2_subdev_pad_ops mt9m032_pad_ops = {
	.enum_mbus_code = mt9m032_enum_mbus_code,
	.enum_frame_size = mt9m032_enum_frame_size,
	.get_fmt = mt9m032_get_pad_format,
	.set_fmt = mt9m032_set_pad_format,
	.set_crop = mt9m032_set_pad_crop,
	.get_crop = mt9m032_get_pad_crop,
};

static const struct v4l2_subdev_ops mt9m032_ops = {
	.core = &mt9m032_core_ops,
	.video = &mt9m032_video_ops,
	.pad = &mt9m032_pad_ops,
};

/* -----------------------------------------------------------------------------
 * Driver initialization and probing
 */

static int mt9m032_probe(struct i2c_client *client,
			 const struct i2c_device_id *devid)
{
	struct i2c_adapter *adapter = client->adapter;
	struct mt9m032 *sensor;
	int chip_version;
	int ret;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
		dev_warn(&client->dev,
			 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
		return -EIO;
	}

	if (!client->dev.platform_data)
		return -ENODEV;

	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
	if (sensor == NULL)
		return -ENOMEM;

	mutex_init(&sensor->lock);

	sensor->pdata = client->dev.platform_data;

	v4l2_i2c_subdev_init(&sensor->subdev, client, &mt9m032_ops);
	sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;

	chip_version = mt9m032_read(client, MT9M032_CHIP_VERSION);
	if (chip_version != MT9M032_CHIP_VERSION_VALUE) {
		dev_err(&client->dev, "MT9M032 not detected, wrong version "
			"0x%04x\n", chip_version);
		ret = -ENODEV;
		goto error_sensor;
	}

	dev_info(&client->dev, "MT9M032 detected at address 0x%02x\n",
		 client->addr);

	sensor->frame_interval.numerator = 1;
	sensor->frame_interval.denominator = 30;

	sensor->crop.left = MT9M032_COLUMN_START_DEF;
	sensor->crop.top = MT9M032_ROW_START_DEF;
	sensor->crop.width = MT9M032_COLUMN_SIZE_DEF;
	sensor->crop.height = MT9M032_ROW_SIZE_DEF;

	sensor->format.width = sensor->crop.width;
	sensor->format.height = sensor->crop.height;
	sensor->format.code = V4L2_MBUS_FMT_Y8_1X8;
	sensor->format.field = V4L2_FIELD_NONE;
	sensor->format.colorspace = V4L2_COLORSPACE_SRGB;

	v4l2_ctrl_handler_init(&sensor->ctrls, 4);

	v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
			  V4L2_CID_GAIN, 0, 127, 1, 64);

	sensor->hflip = v4l2_ctrl_new_std(&sensor->ctrls,
					  &mt9m032_ctrl_ops,
					  V4L2_CID_HFLIP, 0, 1, 1, 0);
	sensor->vflip = v4l2_ctrl_new_std(&sensor->ctrls,
					  &mt9m032_ctrl_ops,
					  V4L2_CID_VFLIP, 0, 1, 1, 0);

	v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
			  V4L2_CID_EXPOSURE, MT9M032_SHUTTER_WIDTH_MIN,
			  MT9M032_SHUTTER_WIDTH_MAX, 1,
			  MT9M032_SHUTTER_WIDTH_DEF);

	if (sensor->ctrls.error) {
		ret = sensor->ctrls.error;
		dev_err(&client->dev, "control initialization error %d\n", ret);
		goto error_ctrl;
	}

	v4l2_ctrl_cluster(2, &sensor->hflip);

	sensor->subdev.ctrl_handler = &sensor->ctrls;
	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
	ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad, 0);
	if (ret < 0)
		goto error_ctrl;

	ret = mt9m032_write(client, MT9M032_RESET, 1);	/* reset on */
	if (ret < 0)
		goto error_entity;
	mt9m032_write(client, MT9M032_RESET, 0);	/* reset off */
	if (ret < 0)
		goto error_entity;

	ret = mt9m032_setup_pll(sensor);
	if (ret < 0)
		goto error_entity;
	usleep_range(10000, 11000);

	ret = v4l2_ctrl_handler_setup(&sensor->ctrls);
	if (ret < 0)
		goto error_entity;

	/* SIZE */
	ret = mt9m032_update_geom_timing(sensor);
	if (ret < 0)
		goto error_entity;

	ret = mt9m032_write(client, 0x41, 0x0000);	/* reserved !!! */
	if (ret < 0)
		goto error_entity;
	ret = mt9m032_write(client, 0x42, 0x0003);	/* reserved !!! */
	if (ret < 0)
		goto error_entity;
	ret = mt9m032_write(client, 0x43, 0x0003);	/* reserved !!! */
	if (ret < 0)
		goto error_entity;
	ret = mt9m032_write(client, 0x7f, 0x0000);	/* reserved !!! */
	if (ret < 0)
		goto error_entity;
	if (sensor->pdata->invert_pixclock) {
		ret = mt9m032_write(client, MT9M032_PIX_CLK_CTRL,
				    MT9M032_PIX_CLK_CTRL_INV_PIXCLK);
		if (ret < 0)
			goto error_entity;
	}

	ret = mt9m032_write(client, MT9M032_RESTART, 1); /* Restart on */
	if (ret < 0)
		goto error_entity;
	msleep(100);
	ret = mt9m032_write(client, MT9M032_RESTART, 0); /* Restart off */
	if (ret < 0)
		goto error_entity;
	msleep(100);
	ret = update_formatter2(sensor, false);
	if (ret < 0)
		goto error_entity;

	return ret;

error_entity:
	media_entity_cleanup(&sensor->subdev.entity);
error_ctrl:
	v4l2_ctrl_handler_free(&sensor->ctrls);
error_sensor:
	mutex_destroy(&sensor->lock);
	kfree(sensor);
	return ret;
}

static int mt9m032_remove(struct i2c_client *client)
{
	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
	struct mt9m032 *sensor = to_mt9m032(subdev);

	v4l2_device_unregister_subdev(&sensor->subdev);
	v4l2_ctrl_handler_free(&sensor->ctrls);
	media_entity_cleanup(&sensor->subdev.entity);
	mutex_destroy(&sensor->lock);
	kfree(sensor);
	return 0;
}

static const struct i2c_device_id mt9m032_id_table[] = {
	{ MT9M032_NAME, 0 },
	{ }
};

MODULE_DEVICE_TABLE(i2c, mt9m032_id_table);

static struct i2c_driver mt9m032_i2c_driver = {
	.driver = {
		.name = MT9M032_NAME,
	},
	.probe = mt9m032_probe,
	.remove = mt9m032_remove,
	.id_table = mt9m032_id_table,
};
Esempio n. 5
0
static int lm3554_probe(struct i2c_client *client,
				  const struct i2c_device_id *id)
{
	int err;
	struct lm3554 *flash;

#ifndef CONFIG_GMIN_INTEL_MID
	if (client->dev.platform_data == NULL) {
		dev_err(&client->dev, "no platform data\n");
		return -ENODEV;
	}
#endif

	flash = kzalloc(sizeof(*flash), GFP_KERNEL);
	if (!flash) {
		dev_err(&client->dev, "out of memory\n");
		return -ENOMEM;
	}

	flash->pdata = client->dev.platform_data;

#ifdef CONFIG_GMIN_INTEL_MID
	if (!flash->pdata || ACPI_COMPANION(&client->dev))
		flash->pdata = lm3554_platform_data_func(client);
#endif

	v4l2_i2c_subdev_init(&flash->sd, client, &lm3554_ops);
	flash->sd.internal_ops = &lm3554_internal_ops;
	flash->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	flash->mode = ATOMISP_FLASH_MODE_OFF;
	flash->timeout = LM3554_MAX_TIMEOUT / LM3554_TIMEOUT_STEPSIZE - 1;

	err = media_entity_init(&flash->sd.entity, 0, NULL, 0);
	if (err) {
		dev_err(&client->dev, "error initialize a media entity.\n");
		goto fail1;
	}

	flash->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;

	mutex_init(&flash->power_lock);

	setup_timer(&flash->flash_off_delay, lm3554_flash_off_delay,
		    (unsigned long)client);

	err = lm3554_gpio_init(client);
	if (err) {
		dev_err(&client->dev, "gpio request/direction_output fail");
		goto fail2;
	}

#ifdef CONFIG_GMIN_INTEL_MID
	if (ACPI_HANDLE(&client->dev))
		err = atomisp_register_i2c_module(&flash->sd, NULL, LED_FLASH);
#endif
	return 0;
fail2:
	media_entity_cleanup(&flash->sd.entity);
fail1:
	v4l2_device_unregister_subdev(&flash->sd);
	kfree(flash);

	return err;
}
Esempio n. 6
0
static int __devinit msm_vpe_probe(struct platform_device *pdev)
{
	int rc = 0;
	struct msm_cam_subdev_info sd_info;

	D("%s: device id = %d\n", __func__, pdev->id);
	vpe_ctrl = kzalloc(sizeof(struct vpe_ctrl_type), GFP_KERNEL);
	if (!vpe_ctrl) {
		pr_err("%s: not enough memory\n", __func__);
		return -ENOMEM;
	}

	v4l2_subdev_init(&vpe_ctrl->subdev, &msm_vpe_subdev_ops);
	v4l2_set_subdevdata(&vpe_ctrl->subdev, vpe_ctrl);
	vpe_ctrl->subdev.internal_ops = &msm_vpe_internal_ops;
	vpe_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	snprintf(vpe_ctrl->subdev.name, sizeof(vpe_ctrl->subdev.name), "vpe");
	platform_set_drvdata(pdev, &vpe_ctrl->subdev);

	media_entity_init(&vpe_ctrl->subdev.entity, 0, NULL, 0);
	vpe_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	vpe_ctrl->subdev.entity.group_id = VPE_DEV;
	vpe_ctrl->subdev.entity.name = vpe_ctrl->subdev.name;

	vpe_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;

	vpe_ctrl->vpemem = platform_get_resource_byname(pdev,
					IORESOURCE_MEM, "vpe");
	if (!vpe_ctrl->vpemem) {
		pr_err("%s: no mem resource?\n", __func__);
		rc = -ENODEV;
		goto vpe_no_resource;
	}
	vpe_ctrl->vpeirq = platform_get_resource_byname(pdev,
					IORESOURCE_IRQ, "vpe");
	if (!vpe_ctrl->vpeirq) {
		pr_err("%s: no irq resource?\n", __func__);
		rc = -ENODEV;
		goto vpe_no_resource;
	}

	vpe_ctrl->vpeio = request_mem_region(vpe_ctrl->vpemem->start,
		resource_size(vpe_ctrl->vpemem), pdev->name);
	if (!vpe_ctrl->vpeio) {
		pr_err("%s: no valid mem region\n", __func__);
		rc = -EBUSY;
		goto vpe_no_resource;
	}

	rc = request_irq(vpe_ctrl->vpeirq->start, vpe_parse_irq,
		IRQF_TRIGGER_RISING, "vpe", 0);
	if (rc < 0) {
		release_mem_region(vpe_ctrl->vpemem->start,
			resource_size(vpe_ctrl->vpemem));
		pr_err("%s: irq request fail\n", __func__);
		rc = -EBUSY;
		goto vpe_no_resource;
	}

	vpe_ctrl->fs_vpe = regulator_get(&pdev->dev, "vdd");
	if (IS_ERR(vpe_ctrl->fs_vpe)) {
		pr_err("%s: Regulator FS_VPE get failed %ld\n", __func__,
			PTR_ERR(vpe_ctrl->fs_vpe));
		vpe_ctrl->fs_vpe = NULL;
	}

	disable_irq(vpe_ctrl->vpeirq->start);

#ifdef CONFIG_MSM_IOMMU
	/*get device context for IOMMU*/
	vpe_ctrl->iommu_ctx_src = msm_iommu_get_ctx("vpe_src"); /*re-confirm*/
	vpe_ctrl->iommu_ctx_dst = msm_iommu_get_ctx("vpe_dst"); /*re-confirm*/
	if (!vpe_ctrl->iommu_ctx_src || !vpe_ctrl->iommu_ctx_dst) {
		release_mem_region(vpe_ctrl->vpemem->start,
			resource_size(vpe_ctrl->vpemem));
		pr_err("%s: No iommu fw context found\n", __func__);
		rc = -ENODEV;
		goto vpe_no_resource;
	}
#endif

	atomic_set(&vpe_ctrl->active, 0);
	vpe_ctrl->pdev = pdev;
	sd_info.sdev_type = VPE_DEV;
	sd_info.sd_index = pdev->id;
	sd_info.irq_num = vpe_ctrl->vpeirq->start;
	msm_cam_register_subdev_node(&vpe_ctrl->subdev, &sd_info);
	vpe_ctrl->subdev.entity.revision = vpe_ctrl->subdev.devnode->num;
	msm_queue_init(&vpe_ctrl->eventData_q, "ackevents");

	return 0;

vpe_no_resource:
	pr_err("%s: VPE Probe failed.\n", __func__);
	kfree(vpe_ctrl);
	return rc;
}
Esempio n. 7
0
static int32_t msm_flash_platform_probe(struct platform_device *pdev)
{
	int32_t rc = 0;
	struct msm_flash_ctrl_t *flash_ctrl = NULL;
	struct msm_camera_cci_client *cci_client = NULL;

	CDBG("Enter");
	if (!pdev->dev.of_node) {
		pr_err("of_node NULL\n");
		return -EINVAL;
	}

	flash_ctrl = kzalloc(sizeof(struct msm_flash_ctrl_t), GFP_KERNEL);
	if (!flash_ctrl) {
		pr_err("%s:%d failed no memory\n", __func__, __LINE__);
		return -ENOMEM;
	}

	memset(flash_ctrl, 0, sizeof(struct msm_flash_ctrl_t));

	flash_ctrl->pdev = pdev;

	rc = msm_flash_get_dt_data(pdev->dev.of_node, flash_ctrl);
	if (rc < 0) {
		pr_err("%s:%d msm_flash_get_dt_data failed\n",
			__func__, __LINE__);
		kfree(flash_ctrl);
		return -EINVAL;
	}

	flash_ctrl->flash_state = MSM_CAMERA_FLASH_RELEASE;
	flash_ctrl->power_info.dev = &flash_ctrl->pdev->dev;
	flash_ctrl->flash_device_type = MSM_CAMERA_PLATFORM_DEVICE;
	flash_ctrl->flash_mutex = &msm_flash_mutex;
	flash_ctrl->flash_i2c_client.i2c_func_tbl = &msm_sensor_cci_func_tbl;
	flash_ctrl->flash_i2c_client.cci_client = kzalloc(
		sizeof(struct msm_camera_cci_client), GFP_KERNEL);
	if (!flash_ctrl->flash_i2c_client.cci_client) {
		kfree(flash_ctrl);
		pr_err("failed no memory\n");
		return -ENOMEM;
	}

	cci_client = flash_ctrl->flash_i2c_client.cci_client;
	cci_client->cci_subdev = msm_cci_get_subdev();
	cci_client->cci_i2c_master = flash_ctrl->cci_i2c_master;

	/* Initialize sub device */
	v4l2_subdev_init(&flash_ctrl->msm_sd.sd, &msm_flash_subdev_ops);
	v4l2_set_subdevdata(&flash_ctrl->msm_sd.sd, flash_ctrl);

	flash_ctrl->msm_sd.sd.internal_ops = &msm_flash_internal_ops;
	flash_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	snprintf(flash_ctrl->msm_sd.sd.name,
		ARRAY_SIZE(flash_ctrl->msm_sd.sd.name),
		"msm_camera_flash");
	media_entity_init(&flash_ctrl->msm_sd.sd.entity, 0, NULL, 0);
	flash_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	flash_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_FLASH;
	flash_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x1;
	msm_sd_register(&flash_ctrl->msm_sd);

	CDBG("%s:%d flash sd name = %s", __func__, __LINE__,
		flash_ctrl->msm_sd.sd.entity.name);
	msm_flash_v4l2_subdev_fops = v4l2_subdev_fops;
#ifdef CONFIG_COMPAT
	msm_flash_v4l2_subdev_fops.compat_ioctl32 =
		msm_flash_subdev_fops_ioctl;
#endif
	flash_ctrl->msm_sd.sd.devnode->fops = &msm_flash_v4l2_subdev_fops;

	if (flash_ctrl->flash_driver_type == FLASH_DRIVER_PMIC)
		rc = msm_torch_create_classdev(pdev, &flash_ctrl);

	CDBG("probe success\n");
	return rc;
}
Esempio n. 8
0
static int32_t msm_tcs_platform_probe(struct platform_device *pdev)
{
	int32_t rc = 0;

	struct msm_camera_cci_client *cci_client = NULL;
	CDBG("Enter\n");

	if (!pdev->dev.of_node) {
		CDBG("of_node NULL : %d\n", EINVAL);
		return -EINVAL;
	}

	rc = of_property_read_u32((&pdev->dev)->of_node, "cell-index",
							  &pdev->id);
	CDBG("cell-index %d, rc %d\n", pdev->id, rc);
	if (rc < 0) {
		pr_err("failed rc %d\n", rc);
		return rc;
	}

	rc = of_property_read_u32((&pdev->dev)->of_node, "qcom,cci-master",
							&msm_tcs_t.cci_master);
	CDBG("qcom,cci-master %d, rc %d\n", msm_tcs_t.cci_master, rc);
	if (rc < 0) {
		pr_err("failed rc %d\n", rc);
		return rc;
	}

	msm_tcs_t.tcs_mutex = &msm_tcs_mutex;
	msm_tcs_t.pdev = pdev;

	msm_tcs_t.tcs_device_type = MSM_CAMERA_PLATFORM_DEVICE;
	msm_tcs_t.i2c_client.i2c_func_tbl = &msm_sensor_cci_func_tbl;
	msm_tcs_t.i2c_client.cci_client = kzalloc(sizeof(struct msm_camera_cci_client), GFP_KERNEL);
	if (!msm_tcs_t.i2c_client.cci_client) {
		pr_err("failed no memory\n");
		return -ENOMEM;
	}

	msm_tcs_t.i2c_client.cci_client->sid = 0x39;    //Slave address
	msm_tcs_t.i2c_client.cci_client->retries = 3;
	msm_tcs_t.i2c_client.cci_client->id_map = 0;

	msm_tcs_t.i2c_client.cci_client->cci_i2c_master = MASTER_0;

	msm_tcs_t.i2c_client.addr_type = MSM_CAMERA_I2C_BYTE_ADDR;

	cci_client = msm_tcs_t.i2c_client.cci_client;
	cci_client->cci_subdev = msm_cci_get_subdev();
	v4l2_subdev_init(&msm_tcs_t.msm_sd.sd,
					 msm_tcs_t.tcs_v4l2_subdev_ops);
	v4l2_set_subdevdata(&msm_tcs_t.msm_sd.sd, &msm_tcs_t);
	msm_tcs_t.msm_sd.sd.internal_ops = &msm_tcs_internal_ops;
	msm_tcs_t.msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	snprintf(msm_tcs_t.msm_sd.sd.name,
			 ARRAY_SIZE(msm_tcs_t.msm_sd.sd.name), "msm_tcs");
	media_entity_init(&msm_tcs_t.msm_sd.sd.entity, 0, NULL, 0);
	msm_tcs_t.msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	msm_tcs_t.msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_TCS;
	msm_tcs_t.msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
	msm_sd_register(&msm_tcs_t.msm_sd);
	msm_tcs_t.tcs_state = TCS_POWER_DOWN;

	msm_tcs_v4l2_subdev_fops = v4l2_subdev_fops;
#ifdef CONFIG_COMPAT
	msm_tcs_v4l2_subdev_fops.compat_ioctl32 = msm_tcs_subdev_fops_ioctl;
#endif
	msm_tcs_t.msm_sd.sd.devnode->fops = &msm_tcs_v4l2_subdev_fops;

	msm_tcs_t.sid_tcs = msm_tcs_t.i2c_client.cci_client->sid;
	msm_tcs_t.tcs_func_tbl = NULL;
	msm_tcs_t.exit_workqueue = 1;
	msm_tcs_t.pause_workqueue = 0;
	msm_tcs_t.max_i2c_fail_thres = 5;
	msm_tcs_t.i2c_fail_cnt = 0;

	CDBG("Exit\n");

	return rc;
}
Esempio n. 9
0
static int vfe_probe(struct platform_device *pdev)
{
	struct vfe_device *vfe_dev;
	/*struct msm_cam_subdev_info sd_info;*/
	const struct of_device_id *match_dev;
	int rc = 0;

	struct msm_iova_partition vfe_partition = {
		.start = SZ_128K,
		.size = SZ_2G - SZ_128K,
	};
	struct msm_iova_layout vfe_layout = {
		.partitions = &vfe_partition,
		.npartitions = 1,
		.client_name = "vfe",
		.domain_flags = 0,
	};

	vfe_dev = kzalloc(sizeof(struct vfe_device), GFP_KERNEL);
	if (!vfe_dev) {
		pr_err("%s: no enough memory\n", __func__);
		rc = -ENOMEM;
		goto end;
	}

	if (pdev->dev.of_node) {
		of_property_read_u32((&pdev->dev)->of_node,
			"cell-index", &pdev->id);
		match_dev = of_match_device(msm_vfe_dt_match, &pdev->dev);
		if (!match_dev) {
			pr_err("%s: No vfe hardware info\n", __func__);
			rc = -EINVAL;
			goto probe_fail;
		}
		vfe_dev->hw_info =
			(struct msm_vfe_hardware_info *) match_dev->data;
	} else {
		vfe_dev->hw_info = (struct msm_vfe_hardware_info *)
			platform_get_device_id(pdev)->driver_data;
	}

	if (!vfe_dev->hw_info) {
		pr_err("%s: No vfe hardware info\n", __func__);
		rc = -EINVAL;
		goto probe_fail;
	}
	ISP_DBG("%s: device id = %d\n", __func__, pdev->id);

	vfe_dev->pdev = pdev;
	rc = vfe_dev->hw_info->vfe_ops.core_ops.get_platform_data(vfe_dev);
	if (rc < 0) {
		pr_err("%s: failed to get platform resources\n", __func__);
		rc = -ENOMEM;
		goto probe_fail;
	}

	INIT_LIST_HEAD(&vfe_dev->tasklet_q);
	tasklet_init(&vfe_dev->vfe_tasklet,
		msm_isp_do_tasklet, (unsigned long)vfe_dev);

	v4l2_subdev_init(&vfe_dev->subdev.sd, vfe_dev->hw_info->subdev_ops);
	vfe_dev->subdev.sd.internal_ops =
		vfe_dev->hw_info->subdev_internal_ops;
	snprintf(vfe_dev->subdev.sd.name,
		ARRAY_SIZE(vfe_dev->subdev.sd.name),
		"vfe");
	vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	vfe_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
	v4l2_set_subdevdata(&vfe_dev->subdev.sd, vfe_dev);
	platform_set_drvdata(pdev, &vfe_dev->subdev.sd);
	mutex_init(&vfe_dev->realtime_mutex);
	mutex_init(&vfe_dev->core_mutex);
	spin_lock_init(&vfe_dev->tasklet_lock);
	spin_lock_init(&vfe_dev->shared_data_lock);
	media_entity_init(&vfe_dev->subdev.sd.entity, 0, NULL, 0);
	vfe_dev->subdev.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	vfe_dev->subdev.sd.entity.group_id = MSM_CAMERA_SUBDEV_VFE;
	vfe_dev->subdev.sd.entity.name = pdev->name;
	vfe_dev->subdev.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x2;
	rc = msm_sd_register(&vfe_dev->subdev);
	if (rc != 0) {
		pr_err("%s: msm_sd_register error = %d\n", __func__, rc);
		goto probe_fail;
	}

	vfe_dev->buf_mgr = &vfe_buf_mgr;
	v4l2_subdev_notify(&vfe_dev->subdev.sd,
		MSM_SD_NOTIFY_REQ_CB, &vfe_vb2_ops);
	rc = msm_isp_create_isp_buf_mgr(vfe_dev->buf_mgr,
		&vfe_vb2_ops, &vfe_layout);
	if (rc < 0) {
		pr_err("%s: Unable to create buffer manager\n", __func__);
		rc = -EINVAL;
		goto probe_fail;
	}
	/* create secure context banks*/
	if (vfe_dev->hw_info->num_iommu_secure_ctx) {
		/*secure vfe layout*/
		struct msm_iova_layout vfe_secure_layout = {
			.partitions = &vfe_partition,
			.npartitions = 1,
			.client_name = "vfe_secure",
			.domain_flags = 0,
			.is_secure = MSM_IOMMU_DOMAIN_SECURE,
		};
		rc = msm_isp_create_secure_domain(vfe_dev->buf_mgr,
			&vfe_secure_layout);
		if (rc < 0) {
			pr_err("%s: fail to create secure domain\n", __func__);
			msm_sd_unregister(&vfe_dev->subdev);
			rc = -EINVAL;
			goto probe_fail;
		}
	}

	vfe_dev->buf_mgr->ops->register_ctx(vfe_dev->buf_mgr,
		&vfe_dev->iommu_ctx[0], &vfe_dev->iommu_secure_ctx[0],
		vfe_dev->hw_info->num_iommu_ctx,
		vfe_dev->hw_info->num_iommu_secure_ctx);

	vfe_dev->buf_mgr->init_done = 1;
	vfe_dev->vfe_open_cnt = 0;
	return rc;

probe_fail:
	kfree(vfe_dev);
end:
	return rc;
}

static struct platform_driver vfe_driver = {
	.probe = vfe_probe,
	.driver = {
		.name = "msm_vfe",
		.owner = THIS_MODULE,
		.of_match_table = msm_vfe_dt_match,
	},
	.id_table = msm_vfe_dev_id,
};

static int __init msm_vfe_init_module(void)
{
	return platform_driver_register(&vfe_driver);
}

static void __exit msm_vfe_exit_module(void)
{
	platform_driver_unregister(&vfe_driver);
}

module_init(msm_vfe_init_module);
module_exit(msm_vfe_exit_module);
MODULE_DESCRIPTION("MSM VFE driver");
MODULE_LICENSE("GPL v2");
Esempio n. 10
0
/*
 * public functions
 */
struct nxp_video *create_nxp_video(char *name, u32 type,
        struct v4l2_device *v4l2_dev, void *vb2_alloc_ctx)
{
    int ret;
    struct vb2_queue *vbq = NULL;
    struct nxp_video *me = kzalloc(sizeof(struct nxp_video), GFP_KERNEL);
    int pad_num = 0;

    if (!me) {
        pr_err("%s: failed to allocate me!!!\n", __func__);
        return NULL;
    }

    snprintf(me->name, sizeof(me->name), "%s", name);
    snprintf(me->vdev.name, sizeof(me->vdev.name), "%s", name);

    me->type          = type;
    me->v4l2_dev      = v4l2_dev;
    me->vb2_alloc_ctx = vb2_alloc_ctx;

    /* pad init */
    /* TODO */
#if 0
    switch (type) {
    case NXP_VIDEO_TYPE_CAPTURE:
        /**
         * capture subdev -> capture ->
         * m2m subdev or out subdev
         */
        me->pads[0].flags = MEDIA_PAD_FL_SINK;
        me->pads[1].flags = MEDIA_PAD_FL_SOURCE;
        pad_num = 2;
        break;

    case NXP_VIDEO_TYPE_OUT:
        /**
         * out -> out subdev
         */
        me->pads[0].flags = MEDIA_PAD_FL_SOURCE;
        pad_num = 1;
        break;

    case NXP_VIDEO_TYPE_M2M:
        /**
         * capture video -> m2m subdev ->
         * m2m video -> out subdev
         */
        me->pads[0].flags = MEDIA_PAD_FL_SINK;
        me->pads[1].flags = MEDIA_PAD_FL_SOURCE;
        pad_num = 2;
        break;

    default:
        pr_err("%s: invalid type(%d)\n", __func__, type);
        kfree(me);
        return NULL;
    }
#else
    me->pads[0].flags = MEDIA_PAD_FL_SINK;
    me->pads[1].flags = MEDIA_PAD_FL_SOURCE;
    pad_num = 2;
#endif

    me->vdev.entity.ops = &nxp_media_entity_operations;
    ret = media_entity_init(&me->vdev.entity, pad_num, me->pads, 0);
    if (ret < 0) {
        kfree(me);
        return NULL;
    }

    mutex_init(&me->lock);

    me->register_buffer_consumer = _register_buffer_consumer;
    me->unregister_buffer_consumer = _unregister_buffer_consumer;

    me->vdev.fops      = &nxp_video_fops;
    me->vdev.ioctl_ops = &nxp_video_ioctl_ops;
    me->vdev.v4l2_dev  = v4l2_dev;
    me->vdev.minor     = -1;
    me->vdev.vfl_type  = VFL_TYPE_GRABBER;
    me->vdev.release   = video_device_release;
    me->vdev.lock      = &me->lock;

    if (type != NXP_VIDEO_TYPE_M2M) {
        vbq = kzalloc(sizeof(*vbq), GFP_KERNEL);
        if (!vbq) {
            pr_err("%s: failed to allocate vbq\n", __func__);
            ret = -ENOMEM;
            goto error_vbq_alloc;
        }
        vbq->type     = type == NXP_VIDEO_TYPE_CAPTURE ?
            V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
        vbq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
        vbq->drv_priv = me;
        vbq->ops      = &nxp_vb2_ops;
        vbq->mem_ops  = &vb2_ion_memops;
        ret = vb2_queue_init(vbq);
        if (ret < 0) {
            pr_err("%s: failed to vb2_queue_init()\n", __func__);
            goto error_vbq_init;
        }
        me->vbq = vbq;
    } else {
        /* m2m */
        me->m2m_dev = v4l2_m2m_init(&nxp_m2m_ops);
        if (IS_ERR(me->m2m_dev)) {
            pr_err("%s: failed to v4l2_m2m_init()\n", __func__);
            ret = -ENOMEM;
            goto error_vbq_alloc;
        }
    }

    INIT_LIST_HEAD(&me->source_consumer_list);
    INIT_LIST_HEAD(&me->sink_consumer_list);
    spin_lock_init(&me->lock_consumer);

    video_set_drvdata(&me->vdev, me);

    pr_debug("%s: success!!!\n", __func__);
    return me;

error_vbq_init:
    if (vbq)
        kfree(vbq);
error_vbq_alloc:
    kfree(me);
    return NULL;
}
Esempio n. 11
0
static int32_t msm_tcs_i2c_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
	int rc = 0;
	struct msm_tcs_ctrl_t *tcs_ctrl_t = NULL;
	CDBG("Enter\n");

	if (client == NULL) {
		pr_err("msm_ois_i2c_probe: client is null\n");
		rc = -EINVAL;
		goto probe_failure;
	}

	tcs_ctrl_t = kzalloc(sizeof(struct msm_tcs_ctrl_t),
		GFP_KERNEL);
	if (!tcs_ctrl_t) {
		pr_err("%s:%d failed no memory\n", __func__, __LINE__);
		return -ENOMEM;
	}

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("i2c_check_functionality failed\n");
		goto probe_failure;
	}

	CDBG("client = 0x%p\n", client);
	rc = of_property_read_u32(client->dev.of_node, "cell-index",
		&tcs_ctrl_t->subdev_id);
	CDBG("cell-index %d, rc %d\n", tcs_ctrl_t->subdev_id, rc);
	if (rc < 0) {
		pr_err("failed rc %d\n", rc);
		return rc;
	}

	tcs_ctrl_t->i2c_driver = &msm_tcs_i2c_driver;
	tcs_ctrl_t->i2c_client.client = client;

	tcs_ctrl_t->tcs_device_type = MSM_CAMERA_I2C_DEVICE;
	tcs_ctrl_t->i2c_client.i2c_func_tbl = &msm_sensor_qup_func_tbl;
	tcs_ctrl_t->tcs_v4l2_subdev_ops = &msm_tcs_subdev_ops;
	tcs_ctrl_t->tcs_mutex = &msm_tcs_mutex;

	snprintf(tcs_ctrl_t->msm_sd.sd.name, sizeof(tcs_ctrl_t->msm_sd.sd.name),
			"%s", tcs_ctrl_t->i2c_driver->driver.name);

	v4l2_i2c_subdev_init(&tcs_ctrl_t->msm_sd.sd,
						tcs_ctrl_t->i2c_client.client,
						tcs_ctrl_t->tcs_v4l2_subdev_ops);
	v4l2_set_subdevdata(&tcs_ctrl_t->msm_sd.sd, tcs_ctrl_t);
	tcs_ctrl_t->msm_sd.sd.internal_ops = &msm_tcs_internal_ops;
	tcs_ctrl_t->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	media_entity_init(&tcs_ctrl_t->msm_sd.sd.entity, 0, NULL, 0);
	tcs_ctrl_t->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	tcs_ctrl_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_TCS;
	tcs_ctrl_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
	msm_sd_register(&tcs_ctrl_t->msm_sd);
	tcs_ctrl_t->tcs_state = TCS_POWER_DOWN;

	CDBG("succeeded\n");
	CDBG("Exit\n");

probe_failure:
	return rc;
}
Esempio n. 12
0
static void dvb_register_media_device(struct dvb_device *dvbdev,
				      int type, int minor)
{
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
	int ret = 0, npads;

	if (!dvbdev->adapter->mdev)
		return;

	dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL);
	if (!dvbdev->entity)
		return;

	dvbdev->entity->info.dev.major = DVB_MAJOR;
	dvbdev->entity->info.dev.minor = minor;
	dvbdev->entity->name = dvbdev->name;

	switch (type) {
	case DVB_DEVICE_CA:
	case DVB_DEVICE_DEMUX:
	case DVB_DEVICE_FRONTEND:
		npads = 2;
		break;
	case DVB_DEVICE_NET:
		npads = 0;
		break;
	default:
		npads = 1;
	}

	if (npads) {
		dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads),
				       GFP_KERNEL);
		if (!dvbdev->pads) {
			kfree(dvbdev->entity);
			return;
		}
	}

	switch (type) {
	case DVB_DEVICE_FRONTEND:
		dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_FE;
		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
		dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
		break;
	case DVB_DEVICE_DEMUX:
		dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DEMUX;
		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
		dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
		break;
	case DVB_DEVICE_DVR:
		dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DVR;
		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
		break;
	case DVB_DEVICE_CA:
		dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_CA;
		dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
		dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
		break;
	case DVB_DEVICE_NET:
		dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_NET;
		break;
	default:
		kfree(dvbdev->entity);
		dvbdev->entity = NULL;
		return;
	}

	if (npads)
		ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads, 0);
	if (!ret)
		ret = media_device_register_entity(dvbdev->adapter->mdev,
						   dvbdev->entity);
	if (ret < 0) {
		printk(KERN_ERR
			"%s: media_device_register_entity failed for %s\n",
			__func__, dvbdev->entity->name);
		kfree(dvbdev->pads);
		kfree(dvbdev->entity);
		dvbdev->entity = NULL;
		return;
	}

	printk(KERN_DEBUG "%s: media device '%s' registered.\n",
		__func__, dvbdev->entity->name);
#endif
}
Esempio n. 13
0
static int ispif_probe(struct platform_device *pdev)
{
	int rc;
	struct ispif_device *ispif;

	ispif = kzalloc(sizeof(struct ispif_device), GFP_KERNEL);
	if (!ispif) {
		pr_err("%s: no enough memory\n", __func__);
		return -ENOMEM;
	}

	if (pdev->dev.of_node) {
		of_property_read_u32((&pdev->dev)->of_node,
		"cell-index", &pdev->id);
		rc = of_property_read_u32((&pdev->dev)->of_node,
		"qcom,num-isps", &ispif->hw_num_isps);
		if (rc)
			/* backward compatibility */
			ispif->hw_num_isps = 1;
		/* not an error condition */
		rc = 0;
	}
	rc = msm_ispif_get_clk_info(ispif, pdev,
		ispif_ahb_clk_info, ispif_clk_info);
	if (rc < 0) {
		pr_err("%s: msm_isp_get_clk_info() failed", __func__);
			return -EFAULT;
	}

	mutex_init(&ispif->mutex);
	ispif->mem = platform_get_resource_byname(pdev,
		IORESOURCE_MEM, "ispif");
	if (!ispif->mem) {
		pr_err("%s: no mem resource?\n", __func__);
		rc = -ENODEV;
		goto error;
	}
	ispif->irq = platform_get_resource_byname(pdev,
		IORESOURCE_IRQ, "ispif");
	if (!ispif->irq) {
		pr_err("%s: no irq resource?\n", __func__);
		rc = -ENODEV;
		goto error;
	}
	ispif->io = request_mem_region(ispif->mem->start,
		resource_size(ispif->mem), pdev->name);
	if (!ispif->io) {
		pr_err("%s: no valid mem region\n", __func__);
		rc = -EBUSY;
		goto error;
	}
	ispif->clk_mux_mem = platform_get_resource_byname(pdev,
		IORESOURCE_MEM, "csi_clk_mux");
	if (ispif->clk_mux_mem) {
		ispif->clk_mux_io = request_mem_region(
			ispif->clk_mux_mem->start,
			resource_size(ispif->clk_mux_mem),
			ispif->clk_mux_mem->name);
		if (!ispif->clk_mux_io)
			pr_err("%s: no valid csi_mux region\n", __func__);
	}

	//LGE_CHANGE_S, vdd_vfe to check if vfe is up
        ispif->fs_vfe = regulator_get(&pdev->dev, "vdd_vfe");

	if (ispif->fs_vfe == NULL)
		pr_err("%s: gdsc_vfe is null\n", __func__);
	//LGE_CHANGE_E, vdd_vfe to check if vfe is up

	v4l2_subdev_init(&ispif->msm_sd.sd, &msm_ispif_subdev_ops);
	ispif->msm_sd.sd.internal_ops = &msm_ispif_internal_ops;
	ispif->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;

	snprintf(ispif->msm_sd.sd.name,
		ARRAY_SIZE(ispif->msm_sd.sd.name), MSM_ISPIF_DRV_NAME);
	v4l2_set_subdevdata(&ispif->msm_sd.sd, ispif);

	platform_set_drvdata(pdev, &ispif->msm_sd.sd);

	media_entity_init(&ispif->msm_sd.sd.entity, 0, NULL, 0);
	ispif->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	ispif->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_ISPIF;
	ispif->msm_sd.sd.entity.name = pdev->name;
	ispif->msm_sd.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x1;
	rc = msm_sd_register(&ispif->msm_sd);
	if (rc) {
		pr_err("%s: msm_sd_register error = %d\n", __func__, rc);
		goto error;
	}
	msm_ispif_v4l2_subdev_fops.owner = v4l2_subdev_fops.owner;
	msm_ispif_v4l2_subdev_fops.open = v4l2_subdev_fops.open;
	msm_ispif_v4l2_subdev_fops.unlocked_ioctl = msm_ispif_subdev_fops_ioctl;
	msm_ispif_v4l2_subdev_fops.release = v4l2_subdev_fops.release;
	msm_ispif_v4l2_subdev_fops.poll = v4l2_subdev_fops.poll;
#ifdef CONFIG_COMPAT
	msm_ispif_v4l2_subdev_fops.compat_ioctl32 = msm_ispif_subdev_fops_ioctl;
#endif
	ispif->msm_sd.sd.devnode->fops = &msm_ispif_v4l2_subdev_fops;
	ispif->pdev = pdev;
	ispif->ispif_state = ISPIF_POWER_DOWN;
	ispif->open_cnt = 0;
	return 0;

error:
	mutex_destroy(&ispif->mutex);
	kfree(ispif);
	return rc;
}
Esempio n. 14
0
static int32_t msm_ois_platform_probe(struct platform_device *pdev)
{
	int32_t rc = 0;
	struct msm_camera_cci_client *cci_client = NULL;
	struct msm_ois_ctrl_t *msm_ois_t = NULL;
	struct msm_ois_vreg *vreg_cfg;

	CDBG_I("Enter\n");

	if (!pdev->dev.of_node) {
		pr_err("of_node NULL\n");
		return -EINVAL;
	}

	msm_ois_t = kzalloc(sizeof(struct msm_ois_ctrl_t),
		GFP_KERNEL);
	if (!msm_ois_t) {
		pr_err("%s:%d failed no memory\n", __func__, __LINE__);
		return -ENOMEM;
	}
	rc = of_property_read_u32((&pdev->dev)->of_node, "cell-index",
		&pdev->id);
	CDBG("cell-index %d, rc %d\n", pdev->id, rc);
	if (rc < 0) {
		kfree(msm_ois_t);
		pr_err("failed rc %d\n", rc);
		return rc;
	}
	msm_ois_t->subdev_id = pdev->id;
	rc = of_property_read_u32((&pdev->dev)->of_node, "qcom,cci-master",
		&msm_ois_t->cci_master);
	CDBG("qcom,cci-master %d, rc %d\n", msm_ois_t->cci_master, rc);
	if (rc < 0) {
		kfree(msm_ois_t);
		pr_err("failed rc %d\n", rc);
		return rc;
	}
	if (of_find_property((&pdev->dev)->of_node,
			"qcom,cam-vreg-name", NULL)) {
		vreg_cfg = &msm_ois_t->vreg_cfg;
		rc = msm_camera_get_dt_vreg_data((&pdev->dev)->of_node,
			&vreg_cfg->cam_vreg, &vreg_cfg->num_vreg);
		if (rc < 0) {
			kfree(msm_ois_t);
			pr_err("failed rc %d\n", rc);
			return rc;
		}
	}

	msm_ois_t->ois_v4l2_subdev_ops = &msm_ois_subdev_ops;
	msm_ois_t->ois_mutex = &msm_ois_mutex;
	msm_ois_t->cam_name = pdev->id;

	/* Set platform device handle */
	msm_ois_t->pdev = pdev;
	/* Set device type as platform device */
	msm_ois_t->ois_device_type = MSM_CAMERA_PLATFORM_DEVICE;
	msm_ois_t->i2c_client.i2c_func_tbl = &msm_sensor_cci_func_tbl;
	msm_ois_t->i2c_client.addr_type = MSM_CAMERA_I2C_WORD_ADDR;
	msm_ois_t->i2c_client.cci_client = kzalloc(sizeof(
		struct msm_camera_cci_client), GFP_KERNEL);
	if (!msm_ois_t->i2c_client.cci_client) {
		kfree(msm_ois_t->vreg_cfg.cam_vreg);
		kfree(msm_ois_t);
		pr_err("failed no memory\n");
		return -ENOMEM;
	}

	cci_client = msm_ois_t->i2c_client.cci_client;
	cci_client->cci_subdev = msm_cci_get_subdev();
	cci_client->cci_i2c_master = MASTER_MAX;
	v4l2_subdev_init(&msm_ois_t->msm_sd.sd,
		msm_ois_t->ois_v4l2_subdev_ops);
	v4l2_set_subdevdata(&msm_ois_t->msm_sd.sd, msm_ois_t);
	msm_ois_t->msm_sd.sd.internal_ops = &msm_ois_internal_ops;
	msm_ois_t->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	snprintf(msm_ois_t->msm_sd.sd.name,
		ARRAY_SIZE(msm_ois_t->msm_sd.sd.name), "msm_ois");
	media_entity_init(&msm_ois_t->msm_sd.sd.entity, 0, NULL, 0);
	msm_ois_t->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	msm_ois_t->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_OIS;
	msm_ois_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0xB;
	rc = msm_sd_register(&msm_ois_t->msm_sd);
	//g_ois_i2c_client.cci_client = msm_ois_t->i2c_client.cci_client;

	CDBG("Exit[rc::%d]\n", rc);
	return rc;
}
static int __init msm_sensor_init_module(void)
{
	int ret = 0;
	
	struct device_node	*of_node = NULL;
	
    of_node = of_find_compatible_node(NULL, NULL, "qcom,hw-camera-board-id");
	
	if (of_property_read_string(of_node, "qcom,product-name",
		                &dt_product_name) < 0) {
		dt_product_name = NULL;
		pr_err("%s: don't define support product name.\n",__func__);
	}
	else{
		pr_info("%s product_name = %s\n", __func__, dt_product_name);
	}

	/* Allocate memory for msm_sensor_init control structure */
	s_init = kzalloc(sizeof(struct msm_sensor_init_t), GFP_KERNEL);
	if (!s_init) {
		pr_err("failed: no memory s_init %p", NULL);
		return -ENOMEM;
	}

	CDBG("MSM_SENSOR_INIT_MODULE %p", NULL);

	/* Initialize mutex */
	mutex_init(&s_init->imutex);

	/* Create /dev/v4l-subdevX for msm_sensor_init */
	v4l2_subdev_init(&s_init->msm_sd.sd, &msm_sensor_init_subdev_ops);
	snprintf(s_init->msm_sd.sd.name, sizeof(s_init->msm_sd.sd.name), "%s",
		"msm_sensor_init");
	v4l2_set_subdevdata(&s_init->msm_sd.sd, s_init);
	s_init->msm_sd.sd.internal_ops = &msm_sensor_init_internal_ops;
	s_init->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	media_entity_init(&s_init->msm_sd.sd.entity, 0, NULL, 0);
	s_init->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	s_init->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR_INIT;
	s_init->msm_sd.sd.entity.name = s_init->msm_sd.sd.name;
	s_init->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x6;
	ret = msm_sd_register(&s_init->msm_sd);
	if (ret) {
		CDBG("%s: msm_sd_register error = %d\n", __func__, ret);
		goto error;
	}

	msm_sensor_init_v4l2_subdev_fops = v4l2_subdev_fops;
#ifdef CONFIG_COMPAT
	msm_sensor_init_v4l2_subdev_fops.compat_ioctl32 =
		msm_sensor_init_subdev_fops_ioctl;
#endif
	s_init->msm_sd.sd.devnode->fops =
		&msm_sensor_init_v4l2_subdev_fops;

	init_waitqueue_head(&s_init->state_wait);

	return 0;
error:
	mutex_destroy(&s_init->imutex);
	kfree(s_init);
	return ret;
}
int32_t msm_sensor_bayer_i2c_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
	int rc = 0;
	struct msm_sensor_ctrl_t *s_ctrl;
	CDBG("%s %s_i2c_probe called\n", __func__, client->name);
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s %s i2c_check_functionality failed\n",
			__func__, client->name);
		rc = -EFAULT;
		return rc;
	}

	s_ctrl = (struct msm_sensor_ctrl_t *)(id->driver_data);
	if (s_ctrl->sensor_i2c_client != NULL) {
		s_ctrl->sensor_i2c_client->client = client;
		if (s_ctrl->sensor_i2c_addr != 0)
			s_ctrl->sensor_i2c_client->client->addr =
				s_ctrl->sensor_i2c_addr;
	} else {
		pr_err("%s %s sensor_i2c_client NULL\n",
			__func__, client->name);
		rc = -EFAULT;
		return rc;
	}

	s_ctrl->sensordata = client->dev.platform_data;
	if (s_ctrl->sensordata == NULL) {
		pr_err("%s %s NULL sensor data\n", __func__, client->name);
		return -EFAULT;
	}

	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
	if (rc < 0) {
		pr_err("%s %s power up failed\n", __func__, client->name);
		return rc;
	}

	if (s_ctrl->func_tbl->sensor_match_id)
		rc = s_ctrl->func_tbl->sensor_match_id(s_ctrl);
	else
		rc = msm_sensor_bayer_match_id(s_ctrl);
	if (rc < 0)
		goto probe_fail;

	if (!s_ctrl->wait_num_frames)
		s_ctrl->wait_num_frames = 1;

	pr_err("%s %s probe succeeded\n", __func__, client->name);
	snprintf(s_ctrl->sensor_v4l2_subdev.name,
		sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s", id->name);
	v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,
		s_ctrl->sensor_v4l2_subdev_ops);
	s_ctrl->sensor_v4l2_subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	media_entity_init(&s_ctrl->sensor_v4l2_subdev.entity, 0, NULL, 0);
	s_ctrl->sensor_v4l2_subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	s_ctrl->sensor_v4l2_subdev.entity.group_id = SENSOR_DEV;
	s_ctrl->sensor_v4l2_subdev.entity.name =
		s_ctrl->sensor_v4l2_subdev.name;
	msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
	s_ctrl->sensor_v4l2_subdev.entity.revision =
		s_ctrl->sensor_v4l2_subdev.devnode->num;
	msm_sensor_bayer_eeprom_read(s_ctrl);
	goto power_down;
probe_fail:
	pr_err("%s %s_i2c_probe failed\n", __func__, client->name);
power_down:
	if (rc > 0)
		rc = 0;
	s_ctrl->func_tbl->sensor_power_down(s_ctrl);
	return rc;
}
static int flite_probe(struct platform_device *pdev)
{
	struct resource *mem_res;
	struct resource *regs_res;
	struct flite_dev *flite;
	int ret = -ENODEV;

	if (!pdev->dev.platform_data) {
		dev_err(&pdev->dev, "platform data is NULL\n");
		return -EINVAL;
	}

	flite = kzalloc(sizeof(struct flite_dev), GFP_KERNEL);
	if (!flite)
		return -ENOMEM;

	flite->pdev = pdev;
	flite->pdata = pdev->dev.platform_data;

	flite->id = pdev->id;

	init_waitqueue_head(&flite->irq_queue);
	spin_lock_init(&flite->slock);

	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem_res) {
		dev_err(&pdev->dev, "Failed to get io memory region\n");
		goto p_err1;
	}

	regs_res = request_mem_region(mem_res->start, resource_size(mem_res),
				      pdev->name);
	if (!regs_res) {
		dev_err(&pdev->dev, "Failed to request io memory region\n");
		goto p_err1;
	}

	flite->regs_res = regs_res;
	flite->regs = ioremap(mem_res->start, resource_size(mem_res));
	if (!flite->regs) {
		dev_err(&pdev->dev, "Failed to remap io region\n");
		goto p_err2;
	}

	flite->irq = platform_get_irq(pdev, 0);
	if (flite->irq < 0) {
		dev_err(&pdev->dev, "Failed to get irq\n");
		goto p_err3;
	}

	ret = request_irq(flite->irq, flite_irq_handler, 0, dev_name(&pdev->dev), flite);
	if (ret) {
		dev_err(&pdev->dev, "request_irq failed\n");
		goto p_err3;
	}

	v4l2_subdev_init(&flite->sd, &flite_subdev_ops);
	flite->sd.owner = THIS_MODULE;
	snprintf(flite->sd.name, sizeof(flite->sd.name), "%s.%d\n",
					MODULE_NAME, flite->id);
#if defined(CONFIG_MEDIA_CONTROLLER) && defined(CONFIG_ARCH_EXYNOS5)
	flite->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;

	flite->pads[FLITE_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
	flite->pads[FLITE_PAD_SOURCE_PREVIEW].flags = MEDIA_PAD_FL_SOURCE;
	flite->pads[FLITE_PAD_SOURCE_CAMCORDING].flags = MEDIA_PAD_FL_SOURCE;
	ret = media_entity_init(&flite->sd.entity, FLITE_PADS_NUM,
				flite->pads, 0);
	if (ret < 0)
		goto p_err3;

	flite_init_formats(&flite->sd, NULL);

	flite->sd.internal_ops = &flite_v4l2_internal_ops;
	flite->sd.entity.ops = &flite_media_ops;

	flite->mdev = flite_get_capture_md(MDEV_CAPTURE);
	if (IS_ERR_OR_NULL(flite->mdev))
		goto p_err3;

	ret = v4l2_device_register_subdev(&flite->mdev->v4l2_dev, &flite->sd);
	if (ret)
		goto p_err3;
#endif
	/* This allows to retrieve the platform device id by the host driver */
	v4l2_set_subdevdata(&flite->sd, pdev);

	/* .. and a pointer to the subdev. */
	platform_set_drvdata(pdev, &flite->sd);

	pm_runtime_enable(&pdev->dev);

	flite_info("fimc-lite%d probe success", pdev->id);

	return 0;

p_err3:
	iounmap(flite->regs);
p_err2:
	release_mem_region(regs_res->start, resource_size(regs_res));
p_err1:
	kfree(flite);
	return ret;
}
Esempio n. 18
0
static int csid_probe(struct platform_device *pdev)
{
	struct csid_device *new_csid_dev;
	uint32_t csi_vdd_voltage = 0;
	int rc = 0;
	new_csid_dev = kzalloc(sizeof(struct csid_device), GFP_KERNEL);
	if (!new_csid_dev) {
		pr_err("%s: no enough memory\n", __func__);
		return -ENOMEM;
	}

	new_csid_dev->ctrl_reg = NULL;
	new_csid_dev->ctrl_reg = kzalloc(sizeof(struct csid_ctrl_t),
		GFP_KERNEL);
	if (!new_csid_dev->ctrl_reg) {
		
		kfree(new_csid_dev);
		
		pr_err("%s:%d kzalloc failed\n", __func__, __LINE__);
		return -ENOMEM;
	}

	v4l2_subdev_init(&new_csid_dev->msm_sd.sd, &msm_csid_subdev_ops);
	v4l2_set_subdevdata(&new_csid_dev->msm_sd.sd, new_csid_dev);
	platform_set_drvdata(pdev, &new_csid_dev->msm_sd.sd);
	mutex_init(&new_csid_dev->mutex);

	if (pdev->dev.of_node) {
		rc = of_property_read_u32((&pdev->dev)->of_node,
			"cell-index", &pdev->id);
		if (rc < 0) {
			pr_err("%s:%d failed to read cell-index\n", __func__,
				__LINE__);
			goto csid_no_resource;
		}
		CDBG("%s device id %d\n", __func__, pdev->id);

		rc = of_property_read_u32((&pdev->dev)->of_node,
			"qcom,csi-vdd-voltage", &csi_vdd_voltage);
		if (rc < 0) {
			pr_err("%s:%d failed to read qcom,csi-vdd-voltage\n",
				__func__, __LINE__);
			goto csid_no_resource;
		}
		CDBG("%s:%d reading mipi_csi_vdd is %d\n", __func__, __LINE__,
			csi_vdd_voltage);

		csid_vreg_info[0].min_voltage = csi_vdd_voltage;
		csid_vreg_info[0].max_voltage = csi_vdd_voltage;
	}

	rc = msm_csid_get_clk_info(new_csid_dev, pdev);
	if (rc < 0) {
		pr_err("%s: msm_csid_get_clk_info() failed", __func__);
		return -EFAULT;
	}


	new_csid_dev->mem = platform_get_resource_byname(pdev,
					IORESOURCE_MEM, "csid");
	if (!new_csid_dev->mem) {
		pr_err("%s: no mem resource?\n", __func__);
		rc = -ENODEV;
		goto csid_no_resource;
	}
	new_csid_dev->irq = platform_get_resource_byname(pdev,
					IORESOURCE_IRQ, "csid");
	if (!new_csid_dev->irq) {
		pr_err("%s: no irq resource?\n", __func__);
		rc = -ENODEV;
		goto csid_no_resource;
	}
	new_csid_dev->io = request_mem_region(new_csid_dev->mem->start,
		resource_size(new_csid_dev->mem), pdev->name);
	if (!new_csid_dev->io) {
		pr_err("%s: no valid mem region\n", __func__);
		rc = -EBUSY;
		goto csid_no_resource;
	}

	new_csid_dev->pdev = pdev;
	new_csid_dev->msm_sd.sd.internal_ops = &msm_csid_internal_ops;
	new_csid_dev->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	snprintf(new_csid_dev->msm_sd.sd.name,
			ARRAY_SIZE(new_csid_dev->msm_sd.sd.name), "msm_csid");
	media_entity_init(&new_csid_dev->msm_sd.sd.entity, 0, NULL, 0);
	new_csid_dev->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	new_csid_dev->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_CSID;
	new_csid_dev->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x5;
	msm_sd_register(&new_csid_dev->msm_sd);

	rc = request_irq(new_csid_dev->irq->start, msm_csid_irq,
		IRQF_TRIGGER_RISING, "csid", new_csid_dev);
	if (rc < 0) {
		release_mem_region(new_csid_dev->mem->start,
			resource_size(new_csid_dev->mem));
		pr_err("%s: irq request fail\n", __func__);
		rc = -EBUSY;
		goto csid_no_resource;
	}
	disable_irq(new_csid_dev->irq->start);
	if (rc < 0) {
		release_mem_region(new_csid_dev->mem->start,
			resource_size(new_csid_dev->mem));
		pr_err("%s Error registering irq ", __func__);
		goto csid_no_resource;
	}

	if (of_device_is_compatible(new_csid_dev->pdev->dev.of_node,
		"qcom,csid-v2.0")) {
		new_csid_dev->ctrl_reg->csid_reg = csid_v2_0;
		new_csid_dev->hw_dts_version = CSID_VERSION_V20;
	} else if (of_device_is_compatible(new_csid_dev->pdev->dev.of_node,
		"qcom,csid-v2.2")) {
		new_csid_dev->ctrl_reg->csid_reg = csid_v2_2;
		new_csid_dev->hw_dts_version = CSID_VERSION_V22;
	} else if (of_device_is_compatible(new_csid_dev->pdev->dev.of_node,
		"qcom,csid-v3.0")) {
		new_csid_dev->ctrl_reg->csid_reg = csid_v3_0;
		new_csid_dev->hw_dts_version = CSID_VERSION_V30;
	} else if (of_device_is_compatible(new_csid_dev->pdev->dev.of_node,
		"qcom,csid-v4.0")) {
		new_csid_dev->ctrl_reg->csid_reg = csid_v3_0;
		new_csid_dev->hw_dts_version = CSID_VERSION_V40;
	} else if (of_device_is_compatible(new_csid_dev->pdev->dev.of_node,
		"qcom,csid-v3.1")) {
		new_csid_dev->ctrl_reg->csid_reg = csid_v3_1;
		new_csid_dev->hw_dts_version = CSID_VERSION_V31;
	} else if (of_device_is_compatible(new_csid_dev->pdev->dev.of_node,
		"qcom,csid-v3.2")) {
		new_csid_dev->ctrl_reg->csid_reg = csid_v3_2;
		new_csid_dev->hw_dts_version = CSID_VERSION_V32;
	} else {
		pr_err("%s:%d, invalid hw version : 0x%x", __func__, __LINE__,
		new_csid_dev->hw_dts_version);
		return -EINVAL;
	}

	new_csid_dev->csid_state = CSID_POWER_DOWN;
	return 0;

csid_no_resource:
	mutex_destroy(&new_csid_dev->mutex);
	kfree(new_csid_dev->ctrl_reg);
	kfree(new_csid_dev);
	return 0;
}
Esempio n. 19
0
static int m5mols_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	const struct m5mols_platform_data *pdata =
		client->dev.platform_data;
	struct m5mols_info *info;
	struct v4l2_subdev *sd;
	int ret = 0;

	if (pdata == NULL) {
		dev_err(&client->dev, "No platform data\n");
		return -EINVAL;
	}

	if (!gpio_is_valid(pdata->gpio_rst)) {
		dev_err(&client->dev, "No valid nRST gpio pin.\n");
		return -EINVAL;
	}

	if (!pdata->irq) {
		dev_err(&client->dev, "Interrupt not assigned.\n");
		return -EINVAL;
	}

	info = kzalloc(sizeof(struct m5mols_info), GFP_KERNEL);
	if (info == NULL) {
		dev_err(&client->dev, "Failed to allocate info\n");
		return -ENOMEM;
	}

	info->pdata	= pdata;
	if (info->pdata->set_power)	/* for additional power if needed. */
		info->set_power = pdata->set_power;

	if (info->pdata->irq) {
		INIT_WORK(&info->work, m5mols_irq_work);
		ret = request_irq(info->pdata->irq, m5mols_irq_handler,
				  IRQF_TRIGGER_RISING, MOD_NAME, &info->sd);
		if (ret) {
			dev_err(&client->dev, "Failed to request irq: %d\n", ret);
			return ret;
		}
	}

	ret = gpio_request(info->pdata->gpio_rst, "M5MOLS nRST");
	if (ret) {
		dev_err(&client->dev, "Failed to set gpio, %d\n", ret);
		goto out_gpio;
	}

	gpio_direction_output(info->pdata->gpio_rst, !info->pdata->enable_rst);

	ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), supplies);
	if (ret) {
		dev_err(&client->dev, "Failed to get regulators, %d\n", ret);
		goto out_reg;
	}

	sd = &info->sd;
	strlcpy(sd->name, MOD_NAME, sizeof(sd->name));

	init_waitqueue_head(&info->cap_wait);

	v4l2_i2c_subdev_init(sd, client, &m5mols_ops);
	info->pad.flags = MEDIA_PAD_FL_SOURCE;
	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
	if (ret < 0)
		goto out_reg;

	m5mols_init_formats(sd, NULL);

	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
	sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
	sd->internal_ops = &m5mols_v4l2_internal_ops;
	sd->entity.ops = &m5mols_media_ops;

	info->res_type = M5MOLS_RESTYPE_MONITOR;

	v4l2_info(sd, "%s : m5mols driver probed success\n", __func__);

	return 0;

out_reg:
	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
out_gpio:
	gpio_free(info->pdata->gpio_rst);
	kfree(info);

	return ret;
}
Esempio n. 20
0
static int __devinit csid_probe(struct platform_device *pdev)
{
	struct csid_device *new_csid_dev;
	struct msm_cam_subdev_info sd_info;
	struct intr_table_entry irq_req;

	int rc = 0;
	CDBG("%s:%d called\n", __func__, __LINE__);
	new_csid_dev = kzalloc(sizeof(struct csid_device), GFP_KERNEL);
	if (!new_csid_dev) {
		pr_err("%s: no enough memory\n", __func__);
		return -ENOMEM;
	}

	v4l2_subdev_init(&new_csid_dev->subdev, &msm_csid_subdev_ops);
	new_csid_dev->subdev.internal_ops = &msm_csid_internal_ops;
	new_csid_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	snprintf(new_csid_dev->subdev.name,
			ARRAY_SIZE(new_csid_dev->subdev.name), "msm_csid");
	v4l2_set_subdevdata(&new_csid_dev->subdev, new_csid_dev);
	platform_set_drvdata(pdev, &new_csid_dev->subdev);
	mutex_init(&new_csid_dev->mutex);

	if (pdev->dev.of_node)
		of_property_read_u32((&pdev->dev)->of_node,
			"cell-index", &pdev->id);

	CDBG("%s device id %d\n", __func__, pdev->id);
	new_csid_dev->mem = platform_get_resource_byname(pdev,
					IORESOURCE_MEM, "csid");
	if (!new_csid_dev->mem) {
		pr_err("%s: no mem resource?\n", __func__);
		rc = -ENODEV;
		goto csid_no_resource;
	}
	new_csid_dev->irq = platform_get_resource_byname(pdev,
					IORESOURCE_IRQ, "csid");
	if (!new_csid_dev->irq) {
		pr_err("%s: no irq resource?\n", __func__);
		rc = -ENODEV;
		goto csid_no_resource;
	}
	new_csid_dev->io = request_mem_region(new_csid_dev->mem->start,
		resource_size(new_csid_dev->mem), pdev->name);
	if (!new_csid_dev->io) {
		pr_err("%s: no valid mem region\n", __func__);
		rc = -EBUSY;
		goto csid_no_resource;
	}

	new_csid_dev->pdev = pdev;
	sd_info.sdev_type = CSID_DEV;
	sd_info.sd_index = pdev->id;
	sd_info.irq_num = new_csid_dev->irq->start;
	msm_cam_register_subdev_node(&new_csid_dev->subdev, &sd_info);

	media_entity_init(&new_csid_dev->subdev.entity, 0, NULL, 0);
	new_csid_dev->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	new_csid_dev->subdev.entity.group_id = CSID_DEV;
	new_csid_dev->subdev.entity.name = pdev->name;
	new_csid_dev->subdev.entity.revision =
		new_csid_dev->subdev.devnode->num;

	/* Request for this device irq from the camera server. If the
	 * IRQ Router is present on this target, the interrupt will be
	 * handled by the camera server and the interrupt service
	 * routine called. If the request_irq call returns ENXIO, then
	 * the IRQ Router hardware is not present on this target. We
	 * have to request for the irq ourselves and register the
	 * appropriate interrupt handler. */
	irq_req.cam_hw_idx       = MSM_CAM_HW_CSI0 + pdev->id;
	irq_req.dev_name         = "csid";
	irq_req.irq_idx          = CAMERA_SS_IRQ_2 + pdev->id;
	irq_req.irq_num          = new_csid_dev->irq->start;
	irq_req.is_composite     = 0;
	irq_req.irq_trigger_type = IRQF_TRIGGER_RISING;
	irq_req.num_hwcore       = 1;
	irq_req.subdev_list[0]   = &new_csid_dev->subdev;
	irq_req.data             = (void *)new_csid_dev;
	rc = msm_cam_server_request_irq(&irq_req);
	if (rc == -ENXIO) {
		/* IRQ Router hardware is not present on this hardware.
		 * Request for the IRQ and register the interrupt handler. */
		rc = request_irq(new_csid_dev->irq->start, msm_csid_irq,
			IRQF_TRIGGER_RISING, "csid", new_csid_dev);
		if (rc < 0) {
			release_mem_region(new_csid_dev->mem->start,
				resource_size(new_csid_dev->mem));
			pr_err("%s: irq request fail\n", __func__);
			rc = -EBUSY;
			goto csid_no_resource;
		}
		disable_irq(new_csid_dev->irq->start);
	} else if (rc < 0) {
		release_mem_region(new_csid_dev->mem->start,
			resource_size(new_csid_dev->mem));
		pr_err("%s Error registering irq ", __func__);
		goto csid_no_resource;
	}

	new_csid_dev->csid_state = CSID_POWER_DOWN;
	return 0;

csid_no_resource:
	mutex_destroy(&new_csid_dev->mutex);
	kfree(new_csid_dev);
	return 0;
}
Esempio n. 21
0
static int __devinit csid_probe(struct platform_device *pdev)
{
	struct csid_device *new_csid_dev;
	uint32_t csi_vdd_voltage = 0;
	int rc = 0;
	new_csid_dev = kzalloc(sizeof(struct csid_device), GFP_KERNEL);
	if (!new_csid_dev) {
		pr_err("%s: no enough memory\n", __func__);
		return -ENOMEM;
	}

	v4l2_subdev_init(&new_csid_dev->msm_sd.sd, &msm_csid_subdev_ops);
	v4l2_set_subdevdata(&new_csid_dev->msm_sd.sd, new_csid_dev);
	platform_set_drvdata(pdev, &new_csid_dev->msm_sd.sd);
	mutex_init(&new_csid_dev->mutex);

	if (pdev->dev.of_node) {
		rc = of_property_read_u32((&pdev->dev)->of_node,
			"cell-index", &pdev->id);
		if (rc < 0) {
			pr_err("%s:%d failed to read cell-index\n", __func__,
				__LINE__);
			goto csid_no_resource;
		}
		CDBG("%s device id %d\n", __func__, pdev->id);

		rc = of_property_read_u32((&pdev->dev)->of_node,
			"qcom,csi-vdd-voltage", &csi_vdd_voltage);
		if (rc < 0) {
			pr_err("%s:%d failed to read qcom,csi-vdd-voltage\n",
				__func__, __LINE__);
			goto csid_no_resource;
		}
		CDBG("%s:%d reading mipi_csi_vdd is %d\n", __func__, __LINE__,
			csi_vdd_voltage);

		csid_vreg_info[0].min_voltage = csi_vdd_voltage;
		csid_vreg_info[0].max_voltage = csi_vdd_voltage;
	}

	new_csid_dev->mem = platform_get_resource_byname(pdev,
					IORESOURCE_MEM, "csid");
	if (!new_csid_dev->mem) {
		pr_err("%s: no mem resource?\n", __func__);
		rc = -ENODEV;
		goto csid_no_resource;
	}
	new_csid_dev->irq = platform_get_resource_byname(pdev,
					IORESOURCE_IRQ, "csid");
	if (!new_csid_dev->irq) {
		pr_err("%s: no irq resource?\n", __func__);
		rc = -ENODEV;
		goto csid_no_resource;
	}
	new_csid_dev->io = request_mem_region(new_csid_dev->mem->start,
		resource_size(new_csid_dev->mem), pdev->name);
	if (!new_csid_dev->io) {
		pr_err("%s: no valid mem region\n", __func__);
		rc = -EBUSY;
		goto csid_no_resource;
	}

	new_csid_dev->pdev = pdev;
	new_csid_dev->msm_sd.sd.internal_ops = &msm_csid_internal_ops;
	new_csid_dev->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	snprintf(new_csid_dev->msm_sd.sd.name,
			ARRAY_SIZE(new_csid_dev->msm_sd.sd.name), "msm_csid");
	media_entity_init(&new_csid_dev->msm_sd.sd.entity, 0, NULL, 0);
	new_csid_dev->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	new_csid_dev->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_CSID;
	new_csid_dev->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x5;
	msm_sd_register(&new_csid_dev->msm_sd);

	rc = request_irq(new_csid_dev->irq->start, msm_csid_irq,
		IRQF_TRIGGER_RISING, "csid", new_csid_dev);
	if (rc < 0) {
		release_mem_region(new_csid_dev->mem->start,
			resource_size(new_csid_dev->mem));
		pr_err("%s: irq request fail\n", __func__);
		rc = -EBUSY;
		goto csid_no_resource;
	}
	disable_irq(new_csid_dev->irq->start);
	if (rc < 0) {
		release_mem_region(new_csid_dev->mem->start,
			resource_size(new_csid_dev->mem));
		pr_err("%s Error registering irq ", __func__);
		goto csid_no_resource;
	}

	new_csid_dev->csid_state = CSID_POWER_DOWN;
/* LGE_CHANGE_S [[email protected]][20130625] : To enter the deep sleep after finish camera open , for google talk */
	wake_lock_init(&new_csid_dev->csid_wake_lock, WAKE_LOCK_SUSPEND, "csid_wake_lock");
/* LGE_CHANGE_E [[email protected]][20130625] : To enter the deep sleep after finish camera open , for google talk */
	return 0;

csid_no_resource:
	mutex_destroy(&new_csid_dev->mutex);
	kfree(new_csid_dev);
	return 0;
}
static int ap1302_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct ap1302_device *dev;
	int ret;
	unsigned int i;

	dev_info(&client->dev, "ap1302 probe called.\n");

	/* allocate device & init sub device */
	dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL);
	if (!dev) {
		dev_err(&client->dev, "%s: out of memory\n", __func__);
		return -ENOMEM;
	}

	mutex_init(&dev->input_lock);

	v4l2_i2c_subdev_init(&(dev->sd), client, &ap1302_ops);

	ret = ap1302_request_firmware(&(dev->sd));
	if (ret) {
		dev_err(&client->dev, "Cannot request ap1302 firmware.\n");
		goto out_free;
	}

	dev->regmap16 = devm_regmap_init_i2c(client, &ap1302_reg16_config);
	if (IS_ERR(dev->regmap16)) {
		ret = PTR_ERR(dev->regmap16);
		dev_err(&client->dev,
			"Failed to allocate 16bit register map: %d\n", ret);
		return ret;
	}

	dev->regmap32 = devm_regmap_init_i2c(client, &ap1302_reg32_config);
	if (IS_ERR(dev->regmap32)) {
		ret = PTR_ERR(dev->regmap32);
		dev_err(&client->dev,
			"Failed to allocate 32bit register map: %d\n", ret);
		return ret;
	}

	if (client->dev.platform_data) {
		ret = ap1302_s_config(&dev->sd, client->dev.platform_data);
		if (ret)
			goto out_free;
	}

	dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	dev->pad.flags = MEDIA_PAD_FL_SOURCE;
	dev->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;

	dev->cntx_res[CONTEXT_PREVIEW].res_num = ARRAY_SIZE(ap1302_preview_res);
	dev->cntx_res[CONTEXT_PREVIEW].res_table = ap1302_preview_res;
	dev->cntx_res[CONTEXT_SNAPSHOT].res_num =
		ARRAY_SIZE(ap1302_snapshot_res);
	dev->cntx_res[CONTEXT_SNAPSHOT].res_table = ap1302_snapshot_res;
	dev->cntx_res[CONTEXT_VIDEO].res_num = ARRAY_SIZE(ap1302_video_res);
	dev->cntx_res[CONTEXT_VIDEO].res_table = ap1302_video_res;

	ret = v4l2_ctrl_handler_init(&dev->ctrl_handler, ARRAY_SIZE(ctrls));
	if (ret) {
		ap1302_remove(client);
		return ret;
	}

	for (i = 0; i < ARRAY_SIZE(ctrls); i++)
		v4l2_ctrl_new_custom(&dev->ctrl_handler, &ctrls[i], NULL);

	if (dev->ctrl_handler.error) {
		ap1302_remove(client);
		return dev->ctrl_handler.error;
	}

	/* Use same lock for controls as for everything else. */
	dev->ctrl_handler.lock = &dev->input_lock;
	dev->sd.ctrl_handler = &dev->ctrl_handler;
	v4l2_ctrl_handler_setup(&dev->ctrl_handler);

	dev->run_mode = v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_RUN_MODE);
	v4l2_ctrl_s_ctrl(dev->run_mode, ATOMISP_RUN_MODE_PREVIEW);

	ret = media_entity_init(&dev->sd.entity, 1, &dev->pad, 0);
	if (ret)
		ap1302_remove(client);
	return ret;
out_free:
	v4l2_device_unregister_subdev(&dev->sd);
	return ret;
}
Esempio n. 23
0
int camera_init_v4l2(struct device *dev, unsigned int *session)
{
	struct msm_video_device *pvdev;
	struct v4l2_device *v4l2_dev;
	int rc = 0;

	pvdev = kzalloc(sizeof(struct msm_video_device),
		GFP_KERNEL);
	if (WARN_ON(!pvdev)) {
		rc = -ENOMEM;
		goto init_end;
	}

	pvdev->vdev = video_device_alloc();
	if (WARN_ON(!pvdev->vdev)) {
		rc = -ENOMEM;
		goto video_fail;
	}

	v4l2_dev = kzalloc(sizeof(struct v4l2_device), GFP_KERNEL);
	if (WARN_ON(!v4l2_dev)) {
		rc = -ENOMEM;
		goto v4l2_fail;
	}

#if defined(CONFIG_MEDIA_CONTROLLER)
	v4l2_dev->mdev = kzalloc(sizeof(struct media_device),
							 GFP_KERNEL);
	if (!v4l2_dev->mdev) {
		rc = -ENOMEM;
		goto mdev_fail;
	}
	strlcpy(v4l2_dev->mdev->model, MSM_CAMERA_NAME,
			sizeof(v4l2_dev->mdev->model));

	v4l2_dev->mdev->dev = dev;

	rc = media_device_register(v4l2_dev->mdev);
	if (WARN_ON(rc < 0))
		goto media_fail;

	rc = media_entity_init(&pvdev->vdev->entity, 0, NULL, 0);
	if (WARN_ON(rc < 0))
		goto entity_fail;
	pvdev->vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
	pvdev->vdev->entity.group_id = QCAMERA_VNODE_GROUP_ID;
#endif

	v4l2_dev->notify = NULL;
	pvdev->vdev->v4l2_dev = v4l2_dev;

	rc = v4l2_device_register(dev, pvdev->vdev->v4l2_dev);
	if (WARN_ON(rc < 0))
		goto register_fail;

	strlcpy(pvdev->vdev->name, "msm-sensor", sizeof(pvdev->vdev->name));
	pvdev->vdev->release  = video_device_release;
	pvdev->vdev->fops     = &camera_v4l2_fops;
	pvdev->vdev->ioctl_ops = &camera_v4l2_ioctl_ops;
	pvdev->vdev->minor     = -1;
	pvdev->vdev->vfl_type  = VFL_TYPE_GRABBER;
	rc = video_register_device(pvdev->vdev,
		VFL_TYPE_GRABBER, -1);
	if (WARN_ON(rc < 0))
		goto video_register_fail;
#if defined(CONFIG_MEDIA_CONTROLLER)
	/* FIXME: How to get rid of this messy? */
	pvdev->vdev->entity.name = video_device_node_name(pvdev->vdev);
#endif

	*session = pvdev->vdev->num;
	atomic_set(&pvdev->opened, 0);
	atomic_set(&pvdev->stream_cnt, 0);
	video_set_drvdata(pvdev->vdev, pvdev);
	goto init_end;

video_register_fail:
	v4l2_device_unregister(pvdev->vdev->v4l2_dev);
register_fail:
#if defined(CONFIG_MEDIA_CONTROLLER)
	media_entity_cleanup(&pvdev->vdev->entity);
entity_fail:
	media_device_unregister(v4l2_dev->mdev);
media_fail:
	kzfree(v4l2_dev->mdev);
mdev_fail:
#endif
	kzfree(v4l2_dev);
v4l2_fail:
	video_device_release(pvdev->vdev);
video_fail:
	kzfree(pvdev);
init_end:
	return rc;
}
static int32_t cam_dummy_platform_probe(struct platform_device *pdev)
{
	int32_t rc = 0;
	const struct of_device_id *match;
	struct msm_video_device *pvdev;

	/* init_waitqueue_head(&cam_dummy_queue.state_wait);*/
	pr_err("%s:%d\n", __func__, __LINE__);
	match = of_match_device(cam_dummy_dt_match, &pdev->dev);

	msm_v4l2_dev = kzalloc(sizeof(*msm_v4l2_dev),
		GFP_KERNEL);
	if (WARN_ON(!msm_v4l2_dev)) {
		rc = -ENOMEM;
		goto probe_end;
	}

	pvdev = kzalloc(sizeof(struct msm_video_device),
		GFP_KERNEL);
	if (WARN_ON(!pvdev)) {
		rc = -ENOMEM;
		goto pvdev_fail;
	}

	pvdev->vdev = video_device_alloc();
	if (WARN_ON(!pvdev->vdev)) {
		rc = -ENOMEM;
		goto video_fail;
	}

#if defined(CONFIG_MEDIA_CONTROLLER)
	msm_v4l2_dev->mdev = kzalloc(sizeof(struct media_device),
		GFP_KERNEL);
	if (!msm_v4l2_dev->mdev) {
		rc = -ENOMEM;
		goto mdev_fail;
	}
	strlcpy(msm_v4l2_dev->mdev->model, MSM_CAMERA_DUMMY_NAME,
			sizeof(msm_v4l2_dev->mdev->model));
	msm_v4l2_dev->mdev->dev = &(pdev->dev);

	rc = media_device_register(msm_v4l2_dev->mdev);
	if (WARN_ON(rc < 0))
		goto media_fail;

	if (WARN_ON((rc == media_entity_init(&pvdev->vdev->entity,
			0, NULL, 0)) < 0))
		goto entity_fail;

	pvdev->vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
	pvdev->vdev->entity.group_id = QCAMERA_VNODE_GROUP_ID;
#endif

	pvdev->vdev->v4l2_dev = msm_v4l2_dev;

	rc = v4l2_device_register(&(pdev->dev), pvdev->vdev->v4l2_dev);
	if (WARN_ON(rc < 0))
		goto register_fail;

	strlcpy(pvdev->vdev->name, "msm-camdummy", sizeof(pvdev->vdev->name));
	pvdev->vdev->release  = video_device_release;
	pvdev->vdev->fops     = &msm_fops_config;
#if defined CONFIG_SEC_CAMERA_TUNING
	pvdev->vdev->ioctl_ops = &msm_v4l2_ioctl_ops;
#endif
	pvdev->vdev->minor     = -1;
	pvdev->vdev->vfl_type  = VFL_TYPE_GRABBER;
	rc = video_register_device(pvdev->vdev,
		VFL_TYPE_GRABBER, -1);
	if (WARN_ON(rc < 0))
		goto v4l2_fail;

#if defined(CONFIG_MEDIA_CONTROLLER)
	/* FIXME: How to get rid of this messy? */
	pvdev->vdev->entity.name = video_device_node_name(pvdev->vdev);
#endif

	atomic_set(&pvdev->opened, 0);
	video_set_drvdata(pvdev->vdev, pvdev);

	goto probe_end;

v4l2_fail:
	v4l2_device_unregister(pvdev->vdev->v4l2_dev);
register_fail:
#if defined(CONFIG_MEDIA_CONTROLLER)
	media_entity_cleanup(&pvdev->vdev->entity);
entity_fail:
	media_device_unregister(msm_v4l2_dev->mdev);
media_fail:
	kzfree(msm_v4l2_dev->mdev);
mdev_fail:
#endif
	video_device_release(pvdev->vdev);
video_fail:
	kzfree(pvdev);
pvdev_fail:
	kzfree(msm_v4l2_dev);
probe_end:
	return rc;
}
static int msm_eeprom_platform_probe(struct platform_device *pdev)
{
	int rc = 0;
	int j = 0;
	uint32_t temp;

	struct msm_camera_cci_client *cci_client = NULL;
	struct msm_eeprom_ctrl_t *e_ctrl = NULL;
	struct msm_eeprom_board_info *eb_info = NULL;
	struct device_node *of_node = pdev->dev.of_node;
	struct msm_camera_power_ctrl_t *power_info = NULL;

	CDBG("%s E\n", __func__);

	e_ctrl = kzalloc(sizeof(*e_ctrl), GFP_KERNEL);
	if (!e_ctrl) {
		pr_err("%s:%d kzalloc failed\n", __func__, __LINE__);
		return -ENOMEM;
	}
	e_ctrl->eeprom_v4l2_subdev_ops = &msm_eeprom_subdev_ops;
	e_ctrl->eeprom_mutex = &msm_eeprom_mutex;

	e_ctrl->is_supported = 0;
	if (!of_node) {
		pr_err("%s dev.of_node NULL\n", __func__);
		return -EINVAL;
	}

	rc = of_property_read_u32(of_node, "cell-index",
		&pdev->id);
	CDBG("cell-index %d, rc %d\n", pdev->id, rc);
	if (rc < 0) {
		pr_err("failed rc %d\n", rc);
		return rc;
	}
	e_ctrl->subdev_id = pdev->id;

	rc = of_property_read_u32(of_node, "qcom,cci-master",
		&e_ctrl->cci_master);
	CDBG("qcom,cci-master %d, rc %d\n", e_ctrl->cci_master, rc);
	if (rc < 0) {
		pr_err("%s failed rc %d\n", __func__, rc);
		return rc;
	}
	rc = of_property_read_u32(of_node, "qcom,slave-addr",
		&temp);
	if (rc < 0) {
		pr_err("%s failed rc %d\n", __func__, rc);
		return rc;
	}

	/* Set platform device handle */
	e_ctrl->pdev = pdev;
	/* Set device type as platform device */
	e_ctrl->eeprom_device_type = MSM_CAMERA_PLATFORM_DEVICE;
	e_ctrl->i2c_client.i2c_func_tbl = &msm_eeprom_cci_func_tbl;
	e_ctrl->i2c_client.cci_client = kzalloc(sizeof(
		struct msm_camera_cci_client), GFP_KERNEL);
	if (!e_ctrl->i2c_client.cci_client) {
		pr_err("%s failed no memory\n", __func__);
		return -ENOMEM;
	}

	e_ctrl->eboard_info = kzalloc(sizeof(
		struct msm_eeprom_board_info), GFP_KERNEL);
	if (!e_ctrl->eboard_info) {
		pr_err("%s failed line %d\n", __func__, __LINE__);
		rc = -ENOMEM;
		goto cciclient_free;
	}
	eb_info = e_ctrl->eboard_info;
	power_info = &eb_info->power_info;
	eb_info->i2c_slaveaddr = temp;

	power_info->clk_info = cam_8974_clk_info;
	power_info->clk_info_size = ARRAY_SIZE(cam_8974_clk_info);
	power_info->dev = &pdev->dev;

	CDBG("qcom,slave-addr = 0x%X\n", eb_info->i2c_slaveaddr);
	cci_client = e_ctrl->i2c_client.cci_client;
	cci_client->cci_subdev = msm_cci_get_subdev();
	cci_client->cci_i2c_master = e_ctrl->cci_master;
	cci_client->sid = eb_info->i2c_slaveaddr >> 1;
	cci_client->retries = 3;
	cci_client->id_map = 0;

	rc = of_property_read_string(of_node, "qcom,eeprom-name",
		&eb_info->eeprom_name);
	CDBG("%s qcom,eeprom-name %s, rc %d\n", __func__,
		eb_info->eeprom_name, rc);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto board_free;
	}

	rc = msm_eeprom_get_dt_data(e_ctrl);
	if (rc)
		goto board_free;

	rc = msm_eeprom_parse_memory_map(of_node, "cal", &e_ctrl->cal_data);
	if (rc < 0)
		goto board_free;

	rc = msm_camera_power_up(power_info, e_ctrl->eeprom_device_type,
		&e_ctrl->i2c_client);
	if (rc) {
		pr_err("failed rc %d\n", rc);
		goto memdata_free;
	}
	rc = read_eeprom_memory(e_ctrl, &e_ctrl->cal_data);
	if (rc < 0) {
		pr_err("%s read_eeprom_memory failed\n", __func__);
		goto power_down;
	}
	for (j = 0; j < e_ctrl->cal_data.num_data; j++)
		CDBG("memory_data[%d] = 0x%X\n", j,
		     e_ctrl->cal_data.mapdata[j]);

	e_ctrl->is_supported |= msm_eeprom_match_crc(&e_ctrl->cal_data);

	rc = msm_camera_power_down(power_info, e_ctrl->eeprom_device_type,
		&e_ctrl->i2c_client);
	if (rc) {
		pr_err("failed rc %d\n", rc);
		goto memdata_free;
	}
	v4l2_subdev_init(&e_ctrl->msm_sd.sd,
		e_ctrl->eeprom_v4l2_subdev_ops);
	v4l2_set_subdevdata(&e_ctrl->msm_sd.sd, e_ctrl);
	platform_set_drvdata(pdev, &e_ctrl->msm_sd.sd);
	e_ctrl->msm_sd.sd.internal_ops = &msm_eeprom_internal_ops;
	e_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	snprintf(e_ctrl->msm_sd.sd.name,
		ARRAY_SIZE(e_ctrl->msm_sd.sd.name), "msm_eeprom");
	media_entity_init(&e_ctrl->msm_sd.sd.entity, 0, NULL, 0);
	e_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	e_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_EEPROM;
	msm_sd_register(&e_ctrl->msm_sd);

	e_ctrl->is_supported = (e_ctrl->is_supported << 1) | 1;
	CDBG("%s X\n", __func__);
	return rc;

power_down:
	msm_camera_power_down(power_info, e_ctrl->eeprom_device_type,
		&e_ctrl->i2c_client);
memdata_free:
	kfree(e_ctrl->cal_data.mapdata);
	kfree(e_ctrl->cal_data.map);
board_free:
	kfree(e_ctrl->eboard_info);
cciclient_free:
	kfree(e_ctrl->i2c_client.cci_client);
	kfree(e_ctrl);
	return rc;
}
int gsc_register_capture_device(struct gsc_dev *gsc)
{
	struct video_device *vfd;
	struct gsc_capture_device *gsc_cap;
	struct gsc_ctx *ctx;
	struct vb2_queue *q;
	int ret = -ENOMEM;

	ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	ctx->gsc_dev	 = gsc;
	ctx->in_path	 = GSC_WRITEBACK;
	ctx->out_path	 = GSC_DMA;
	ctx->state	 = GSC_CTX_CAP;

	vfd = video_device_alloc();
	if (!vfd) {
		printk("Failed to allocate video device\n");
		goto err_ctx_alloc;
	}

	snprintf(vfd->name, sizeof(vfd->name), "%s.capture",
		 dev_name(&gsc->pdev->dev));

	vfd->fops	= &gsc_capture_fops;
	vfd->ioctl_ops	= &gsc_capture_ioctl_ops;
	vfd->v4l2_dev	= &gsc->mdev[MDEV_CAPTURE]->v4l2_dev;
	vfd->minor	= -1;
	vfd->release	= video_device_release;
	vfd->lock	= &gsc->lock;
	vfd->vfl_dir	= VFL_DIR_RX;
	video_set_drvdata(vfd, gsc);

	gsc_cap	= &gsc->cap;
	gsc_cap->vfd = vfd;
	gsc_cap->refcnt = 0;
	gsc_cap->active_buf_cnt = 0;
	gsc_cap->reqbufs_cnt  = 0;

	INIT_LIST_HEAD(&gsc->cap.active_buf_q);
	spin_lock_init(&ctx->slock);
	gsc_cap->ctx = ctx;

	q = &gsc->cap.vbq;
	memset(q, 0, sizeof(*q));
	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
	q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
	q->drv_priv = gsc->cap.ctx;
	q->ops = &gsc_capture_qops;
	q->mem_ops = gsc->vb2->ops;
	q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;

	ret = vb2_queue_init(q);
	if (ret) {
		gsc_err("failed to init vb2_queue");
		goto err_ctx_alloc;
	}

	ret = video_register_device(vfd, VFL_TYPE_GRABBER,
			    EXYNOS_VIDEONODE_GSC_CAP(gsc->id));
	if (ret) {
		gsc_err("failed to register video device");
		goto err_ctx_alloc;
	}

	gsc->cap.vd_pad.flags = MEDIA_PAD_FL_SOURCE;
	ret = media_entity_init(&vfd->entity, 1, &gsc->cap.vd_pad, 0);
	if (ret) {
		gsc_err("failed to initialize entity");
		goto err_ent;
	}

	ret = gsc_capture_create_subdev(gsc);
	if (ret) {
		gsc_err("failed create subdev");
		goto err_sd_reg;
	}

	ret = gsc_capture_create_link(gsc);
	if (ret) {
		gsc_err("failed create link");
		goto err_sd_reg;
	}

	vfd->ctrl_handler = &ctx->ctrl_handler;
	gsc_info("gsc capture driver registered as /dev/video%d", vfd->num);

	return 0;

err_sd_reg:
	media_entity_cleanup(&vfd->entity);
err_ent:
	video_device_release(vfd);
err_ctx_alloc:
	kfree(ctx);

	return ret;
}
static int msm_eeprom_spi_setup(struct spi_device *spi)
{
	struct msm_eeprom_ctrl_t *e_ctrl = NULL;
	struct msm_camera_i2c_client *client = NULL;
	struct msm_camera_spi_client *spi_client;
	struct msm_eeprom_board_info *eb_info;
	struct msm_camera_power_ctrl_t *power_info = NULL;
	int rc = 0;

	e_ctrl = kzalloc(sizeof(*e_ctrl), GFP_KERNEL);
	if (!e_ctrl) {
		pr_err("%s:%d kzalloc failed\n", __func__, __LINE__);
		return -ENOMEM;
	}
	e_ctrl->eeprom_v4l2_subdev_ops = &msm_eeprom_subdev_ops;
	e_ctrl->eeprom_mutex = &msm_eeprom_mutex;
	client = &e_ctrl->i2c_client;
	e_ctrl->is_supported = 0;

	spi_client = kzalloc(sizeof(*spi_client), GFP_KERNEL);
	if (!spi_client) {
		pr_err("%s:%d kzalloc failed\n", __func__, __LINE__);
		kfree(e_ctrl);
		return -ENOMEM;
	}

	rc = of_property_read_u32(spi->dev.of_node, "cell-index",
				  &e_ctrl->subdev_id);
	CDBG("cell-index %d, rc %d\n", e_ctrl->subdev_id, rc);
	if (rc < 0) {
		pr_err("failed rc %d\n", rc);
		goto spi_free;
	}

	e_ctrl->eeprom_device_type = MSM_CAMERA_SPI_DEVICE;
	client->spi_client = spi_client;
	spi_client->spi_master = spi;
	client->i2c_func_tbl = &msm_eeprom_spi_func_tbl;
	client->addr_type = MSM_CAMERA_I2C_3B_ADDR;

	eb_info = kzalloc(sizeof(*eb_info), GFP_KERNEL);
	if (!eb_info) {
                pr_err("%s : eb_info is NULL", __func__);
		goto spi_free;
        }
	e_ctrl->eboard_info = eb_info;
	rc = of_property_read_string(spi->dev.of_node, "qcom,eeprom-name",
		&eb_info->eeprom_name);
	CDBG("%s qcom,eeprom-name %s, rc %d\n", __func__,
		eb_info->eeprom_name, rc);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto board_free;
	}
	power_info = &eb_info->power_info;

	power_info->clk_info = cam_8974_clk_info;
	power_info->clk_info_size = ARRAY_SIZE(cam_8974_clk_info);
	power_info->dev = &spi->dev;

	rc = msm_eeprom_get_dt_data(e_ctrl);
	if (rc < 0) {
                pr_err("%s : msm_eeprom_get_dt_data", __func__);
		goto board_free;
        }

	/* set spi instruction info */
	spi_client->retry_delay = 1;
	spi_client->retries = 0;

	rc = msm_eeprom_spi_parse_of(spi_client);
	if (rc < 0) {
		dev_err(&spi->dev,
			"%s: Error parsing device properties\n", __func__);
		goto board_free;
	}

	/* prepare memory buffer */
	rc = msm_eeprom_parse_memory_map(spi->dev.of_node, "cal",
					 &e_ctrl->cal_data);
	if (rc < 0)
		pr_warn("%s: no cal memory map\n", __func__);

	/* power up eeprom for reading */
	rc = msm_camera_power_up(power_info, e_ctrl->eeprom_device_type,
		&e_ctrl->i2c_client);
	if (rc < 0) {
		pr_err("failed rc %d\n", rc);
		goto caldata_free;
	}

	/* check eeprom id */
	rc = msm_eeprom_match_id(e_ctrl);
	if (rc < 0) {
		pr_err("%s: eeprom not matching %d\n", __func__, rc);
		goto power_down;
	}
	/* read eeprom */
	if (e_ctrl->cal_data.map) {
		rc = read_eeprom_memory(e_ctrl, &e_ctrl->cal_data);
		if (rc < 0) {
			pr_err("%s: read cal data failed\n", __func__);
			goto power_down;
		}
		e_ctrl->is_supported |= msm_eeprom_match_crc(
						&e_ctrl->cal_data);
	}

	rc = msm_camera_power_down(power_info, e_ctrl->eeprom_device_type,
		&e_ctrl->i2c_client);
	if (rc < 0) {
		pr_err("failed rc %d\n", rc);
		goto caldata_free;
	}

	/* initiazlie subdev */
	v4l2_spi_subdev_init(&e_ctrl->msm_sd.sd,
		e_ctrl->i2c_client.spi_client->spi_master,
		e_ctrl->eeprom_v4l2_subdev_ops);
	v4l2_set_subdevdata(&e_ctrl->msm_sd.sd, e_ctrl);
	e_ctrl->msm_sd.sd.internal_ops = &msm_eeprom_internal_ops;
	e_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	media_entity_init(&e_ctrl->msm_sd.sd.entity, 0, NULL, 0);
	e_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	e_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_EEPROM;
	msm_sd_register(&e_ctrl->msm_sd);
	e_ctrl->is_supported = (e_ctrl->is_supported << 1) | 1;
	pr_warn("%s success result=%d supported=%x X\n", __func__, rc,
	     e_ctrl->is_supported);

	return 0;

power_down:
	msm_camera_power_down(power_info, e_ctrl->eeprom_device_type,
		&e_ctrl->i2c_client);
caldata_free:
	kfree(e_ctrl->cal_data.mapdata);
	kfree(e_ctrl->cal_data.map);
board_free:
	kfree(e_ctrl->eboard_info);
spi_free:
	kfree(spi_client);
	kfree(e_ctrl);
	return rc;
}
static int __devinit ak7343_probe(struct i2c_client *client,
				  const struct i2c_device_id *id)
{
	int ret = -1;
	unsigned long vcmid;
	int pwdn = 0;
	struct ak7343 *vcm;
	struct vcm_platform_data *pdata = client->dev.platform_data;
	vcm = kzalloc(sizeof(struct ak7343), GFP_KERNEL);
	if (!vcm) {
		dev_err(&client->dev, "ak7343: failed to allocate ak7343 struct\n");
		return -ENOMEM;
	}
	if (!pdata)
		return -EIO;
	if (pdata->power_domain) {
		vcm->af_vcc = regulator_get(&client->dev,
					pdata->power_domain);
		if (IS_ERR(vcm->af_vcc))
			goto out_af_vcc;

		vcm_power(vcm, 1);
	}

	if (pdata->pwdn_gpio) {
		vcm->pwdn_gpio = pdata->pwdn_gpio;
		if (gpio_request(vcm->pwdn_gpio, "VCM_ENABLE_LOW"))  {
			printk(KERN_ERR "VCM:can't get the gpio resource!\n");
			ret = -EIO;
			goto out_gpio;
		}
		pwdn = gpio_get_value(vcm->pwdn_gpio);
		gpio_direction_output(vcm->pwdn_gpio, pdata->pwdn_en);
	}
	mdelay(20);
	if (ak7343_read(client, 0x00, &vcmid)) {
		printk(KERN_ERR "VCM: ak7343 vcm detect failure!\n");
		goto out_pwdn;
	}
	if (vcm->pwdn_gpio) {
		gpio_direction_output(vcm->pwdn_gpio, pwdn);
		gpio_free(vcm->pwdn_gpio);
	}
	if (vcm->af_vcc)
		vcm_power(vcm, 0);
	v4l2_i2c_subdev_init(&vcm->subdev, client, &ak7343_ops);
	vcm->subdev.internal_ops = &ak7343_v4l2_internal_ops;
	vcm->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	ret = ak7343_init_controls(vcm);
	if (ret < 0)
		goto out;
	ret = media_entity_init(&vcm->subdev.entity, 0, NULL, 0);
	if (ret < 0)
		goto out;
	v4l2_ctrl_handler_setup(&vcm->ctrls);
	printk(KERN_INFO "ak7343 detected!\n");
	return 0;

out:
	v4l2_ctrl_handler_free(&vcm->ctrls);
out_pwdn:
	if (vcm->pwdn_gpio) {
		gpio_direction_output(vcm->pwdn_gpio, pwdn);
		gpio_free(vcm->pwdn_gpio);
	}
out_gpio:
	if (vcm->af_vcc)
		vcm_power(vcm, 0);
out_af_vcc:
	regulator_put(vcm->af_vcc);
	vcm->af_vcc = NULL;
	kfree(vcm);
	return ret;
}
Esempio n. 29
0
int32_t msm_eeprom_i2c_probe(struct i2c_client *client,
	const struct i2c_device_id *id) {
	int rc = 0;
	int32_t j = 0;
	uint32_t temp = 0;
	struct msm_eeprom_ctrl_t *e_ctrl = NULL;
	struct msm_camera_power_ctrl_t *power_info = NULL;
	struct device_node *of_node = client->dev.of_node;
	CDBG("%s E\n", __func__);


	if (!of_node) {
		pr_err("%s of_node NULL\n", __func__);
		return -EINVAL;
	}

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s i2c_check_functionality failed\n", __func__);
		goto probe_failure;
	}

	e_ctrl = kzalloc(sizeof(struct msm_eeprom_ctrl_t), GFP_KERNEL);
	if (!e_ctrl) {
		pr_err("%s:%d kzalloc failed\n", __func__, __LINE__);
		return -ENOMEM;
	}
	e_ctrl->eeprom_v4l2_subdev_ops = &msm_eeprom_subdev_ops;
	e_ctrl->eeprom_mutex = &msm_eeprom_mutex;
	CDBG("%s client = %x\n", __func__, (unsigned int)client);
	e_ctrl->eboard_info = kzalloc(sizeof(
		struct msm_eeprom_board_info), GFP_KERNEL);
	if (!e_ctrl->eboard_info) {
		pr_err("%s:%d board info NULL\n", __func__, __LINE__);
		return -EINVAL;
	}

	rc = of_property_read_u32(of_node, "qcom,slave-addr", &temp);
	if (rc < 0) {
		pr_err("%s failed rc %d\n", __func__, rc);
		return rc;
	}

	power_info = &e_ctrl->eboard_info->power_info;
	e_ctrl->eboard_info->i2c_slaveaddr = temp;
	e_ctrl->i2c_client.client = client;
	e_ctrl->is_supported = 0;

	/* Set device type as I2C */
	e_ctrl->eeprom_device_type = MSM_CAMERA_I2C_DEVICE;
	e_ctrl->i2c_client.i2c_func_tbl = &msm_eeprom_qup_func_tbl;

	if (e_ctrl->eboard_info->i2c_slaveaddr != 0)
		e_ctrl->i2c_client.client->addr =
					e_ctrl->eboard_info->i2c_slaveaddr;
	power_info->clk_info = cam_8960_clk_info;
	power_info->clk_info_size = ARRAY_SIZE(cam_8960_clk_info);
	power_info->dev = &client->dev;

	rc = of_property_read_string(of_node, "qcom,eeprom-name",
		&e_ctrl->eboard_info->eeprom_name);
	CDBG("%s qcom,eeprom-name %s, rc %d\n", __func__,
		e_ctrl->eboard_info->eeprom_name, rc);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto board_free;
	}

	rc = msm_eeprom_get_dt_data(e_ctrl);
	if (rc)
		goto board_free;

	rc = msm_eeprom_alloc_memory_map(e_ctrl, of_node);
	if (rc)
		goto board_free;

	rc = msm_camera_power_up(power_info, e_ctrl->eeprom_device_type,
		&e_ctrl->i2c_client);
	if (rc) {
		pr_err("%s failed power up %d\n", __func__, __LINE__);
		goto memdata_free;
	}
	rc = read_eeprom_memory(e_ctrl);
	if (rc < 0) {
		pr_err("%s read_eeprom_memory failed\n", __func__);
		goto power_down;
	}

	for (j = 0; j < e_ctrl->num_bytes; j++)
		CDBG("memory_data[%d] = 0x%X\n", j, e_ctrl->memory_data[j]);

	rc = msm_camera_power_down(power_info, e_ctrl->eeprom_device_type,
		&e_ctrl->i2c_client);
	if (rc) {
		pr_err("failed rc %d\n", rc);
		goto power_down;
	}

	/*IMPLEMENT READING PART*/
	/* Initialize sub device */
	v4l2_i2c_subdev_init(&e_ctrl->msm_sd.sd,
		e_ctrl->i2c_client.client,
		e_ctrl->eeprom_v4l2_subdev_ops);
	v4l2_set_subdevdata(&e_ctrl->msm_sd.sd, e_ctrl);
	e_ctrl->msm_sd.sd.internal_ops = &msm_eeprom_internal_ops;
	e_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	media_entity_init(&e_ctrl->msm_sd.sd.entity, 0, NULL, 0);
	e_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	e_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_EEPROM;
	msm_sd_register(&e_ctrl->msm_sd);
	e_ctrl->is_supported = 1;
	CDBG("%s success result=%d X\n", __func__, rc);
	return rc;

power_down:
	msm_camera_power_down(power_info, e_ctrl->eeprom_device_type,
		&e_ctrl->i2c_client);
memdata_free:
	kfree(e_ctrl->memory_data);
	kfree(e_ctrl->eboard_info->eeprom_map);
board_free:
	kfree(e_ctrl->eboard_info);
probe_failure:
	pr_err("%s failed! rc = %d\n", __func__, rc);
	return rc;
}
static int __devinit m5mols_probe(struct i2c_client *client,
				  const struct i2c_device_id *id)
{
	const struct m5mols_platform_data *pdata = client->dev.platform_data;
	struct m5mols_info *info;
	struct v4l2_subdev *sd;
	int ret;

	if (pdata == NULL) {
		dev_err(&client->dev, "No platform data\n");
		return -EINVAL;
	}

	if (!gpio_is_valid(pdata->gpio_reset)) {
		dev_err(&client->dev, "No valid RESET GPIO specified\n");
		return -EINVAL;
	}

	if (!client->irq) {
		dev_err(&client->dev, "Interrupt not assigned\n");
		return -EINVAL;
	}

	info = kzalloc(sizeof(struct m5mols_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->pdata = pdata;
	info->set_power	= pdata->set_power;

	ret = gpio_request(pdata->gpio_reset, "M5MOLS_NRST");
	if (ret) {
		dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
		goto out_free;
	}
	gpio_direction_output(pdata->gpio_reset, pdata->reset_polarity);

	ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), supplies);
	if (ret) {
		dev_err(&client->dev, "Failed to get regulators: %d\n", ret);
		goto out_gpio;
	}

	sd = &info->sd;
	v4l2_i2c_subdev_init(sd, client, &m5mols_ops);
	strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;

	sd->internal_ops = &m5mols_subdev_internal_ops;
	info->pad.flags = MEDIA_PAD_FL_SOURCE;
	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
	if (ret < 0)
		goto out_reg;
	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;

	init_waitqueue_head(&info->irq_waitq);
	ret = request_irq(client->irq, m5mols_irq_handler,
			  IRQF_TRIGGER_RISING, MODULE_NAME, sd);
	if (ret) {
		dev_err(&client->dev, "Interrupt request failed: %d\n", ret);
		goto out_me;
	}
	info->res_type = M5MOLS_RESTYPE_MONITOR;
	info->ffmt[0] = m5mols_default_ffmt[0];
	info->ffmt[1] =	m5mols_default_ffmt[1];

	ret = m5mols_sensor_power(info, true);
	if (ret)
		goto out_me;

	ret = m5mols_fw_start(sd);
	if (!ret)
		ret = m5mols_init_controls(info);

	m5mols_sensor_power(info, false);
	if (!ret)
		return 0;
out_me:
	media_entity_cleanup(&sd->entity);
out_reg:
	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
out_gpio:
	gpio_free(pdata->gpio_reset);
out_free:
	kfree(info);
	return ret;
}