Example #1
0
static int chd_dec_open(struct inode *in, struct file *fd)
{
	struct crystalhd_adp *adp = chd_get_adp();
	int rc = 0;
	enum BC_STATUS sts = BC_STS_SUCCESS;
	struct crystalhd_user *uc = NULL;

	BCMLOG_ENTER;
	if (!adp) {
		BCMLOG_ERR("Invalid adp\n");
		return -EINVAL;
	}

	if (adp->cfg_users >= BC_LINK_MAX_OPENS) {
		BCMLOG(BCMLOG_INFO, "Already in use.%d\n", adp->cfg_users);
		return -EBUSY;
	}

	sts = crystalhd_user_open(&adp->cmds, &uc);
	if (sts != BC_STS_SUCCESS) {
		BCMLOG_ERR("cmd_user_open - %d\n", sts);
		rc = -EBUSY;
	}

	adp->cfg_users++;

	fd->private_data = uc;

	return rc;
}
Example #2
0
/* API interfaces */
static long chd_dec_ioctl(struct file *fd, unsigned int cmd, unsigned long ua)
{
	struct crystalhd_adp *adp = chd_get_adp();
	crystalhd_cmd_proc cproc;
	struct crystalhd_user *uc;
	int ret;

	if (!adp || !fd) {
		BCMLOG_ERR("Invalid adp\n");
		return -EINVAL;
	}

	uc = (struct crystalhd_user *)fd->private_data;
	if (!uc) {
		BCMLOG_ERR("Failed to get uc\n");
		return -ENODATA;
	}

	lock_kernel();
	cproc = crystalhd_get_cmd_proc(&adp->cmds, cmd, uc);
	if (!cproc) {
		BCMLOG_ERR("Unhandled command: %d\n", cmd);
		unlock_kernel();
		return -EINVAL;
	}

	ret = chd_dec_api_cmd(adp, ua, uc->uid, cmd, cproc);
	unlock_kernel();
	return ret;
}
Example #3
0
static int chd_dec_open(struct inode *in, struct file *fd)
{
	struct crystalhd_adp *adp = chd_get_adp();
	struct device *dev = &adp->pdev->dev;
	int rc = 0;
	BC_STATUS sts = BC_STS_SUCCESS;
	struct crystalhd_user *uc = NULL;

	dev_dbg(dev, "Entering %s\n", __func__);
	if (!adp) {
		dev_err(dev, "Invalid adp\n");
		return -EINVAL;
	}

	if (adp->cfg_users >= BC_LINK_MAX_OPENS) {
		dev_info(dev, "Already in use.%d\n", adp->cfg_users);
		return -EBUSY;
	}

	sts = crystalhd_user_open(&adp->cmds, &uc);
	if (sts != BC_STS_SUCCESS) {
		dev_err(dev, "cmd_user_open - %d\n", sts);
		rc = -EBUSY;
	}
	else {
		adp->cfg_users++;
		fd->private_data = uc;
	}

	return rc;
}
Example #4
0
static long chd_dec_ioctl(struct file *fd,
			  unsigned int cmd, unsigned long ua)
#endif
{
	struct crystalhd_adp *adp = chd_get_adp();
	struct device *dev = &adp->pdev->dev;
	crystalhd_cmd_proc cproc;
	struct crystalhd_user *uc;

	dev_dbg(dev, "Entering %s\n", __func__);

	if (!adp || !fd) {
		dev_err(chddev(), "Invalid adp\n");
		return -EINVAL;
	}

	uc = fd->private_data;
	if (!uc) {
		dev_err(chddev(), "Failed to get uc\n");
		return -ENODATA;
	}

	cproc = crystalhd_get_cmd_proc(&adp->cmds, cmd, uc);
	if (!cproc && !(adp->cmds.state & BC_LINK_SUSPEND)) {
		dev_err(chddev(), "Unhandled command: %d\n", cmd);
		return -EINVAL;
	}

	return chd_dec_api_cmd(adp, ua, uc->uid, cmd, cproc);
}
Example #5
0
static int chd_dec_close(struct inode *in, struct file *fd)
{
	struct crystalhd_adp *adp = chd_get_adp();
	struct crystalhd_user *uc;

	if (!adp) {
		BCMLOG_ERR("Invalid adp\n");
		return -EINVAL;
	}

	uc = fd->private_data;
	if (!uc) {
		BCMLOG_ERR("Failed to get uc\n");
		return -ENODATA;
	}

	crystalhd_user_close(&adp->cmds, uc);

	adp->cfg_users--;

	return 0;
}
Example #6
0
static int chd_dec_close(struct inode *in, struct file *fd)
{
	struct crystalhd_adp *adp = chd_get_adp();
	struct device *dev = &adp->pdev->dev;
	struct crystalhd_cmd *ctx = &adp->cmds;
	struct crystalhd_user *uc;
	uint32_t mode;

	dev_dbg(dev, "Entering %s\n", __func__);
	if (!adp) {
		dev_err(dev, "Invalid adp\n");
		return -EINVAL;
	}

	uc = fd->private_data;
	if (!uc) {
		dev_err(dev, "Failed to get uc\n");
		return -ENODATA;
	}

	/* Check and close only if we have not flush/closed before */
	/* This is needed because release is not guarenteed to be called immediately on close,
	 * if duplicate file handles exist due to fork etc. This causes problems with close and re-open
	 of the device immediately */

	if(uc->in_use) {
		mode = uc->mode;

		ctx->user[uc->uid].mode = DTS_MODE_INV;
		ctx->user[uc->uid].in_use = 0;

		dev_info(chddev(), "Closing user[%x] handle with mode %x\n", uc->uid, mode);

		if (((mode & 0xFF) == DTS_DIAG_MODE) ||
			((mode & 0xFF) == DTS_PLAYBACK_MODE) ||
			((bc_get_userhandle_count(ctx) == 0) && (ctx->hw_ctx != NULL))) {
			ctx->cin_wait_exit = 1;
			ctx->pwr_state_change = BC_HW_RUNNING;
			/* Stop the HW Capture just in case flush did not get called before stop */
			/* And only if we had actually started it */
			if(ctx->hw_ctx->rx_freeq != NULL) {
				crystalhd_hw_stop_capture(ctx->hw_ctx, true);
				crystalhd_hw_free_dma_rings(ctx->hw_ctx);
			}
			if(ctx->adp->fill_byte_pool)
				crystalhd_destroy_dio_pool(ctx->adp);
			if(ctx->adp->elem_pool_head)
				crystalhd_delete_elem_pool(ctx->adp);
			ctx->state = BC_LINK_INVALID;
			crystalhd_hw_close(ctx->hw_ctx, ctx->adp);
			kfree(ctx->hw_ctx);
			ctx->hw_ctx = NULL;
		}

		uc->in_use = 0;

		if(adp->cfg_users > 0)
			adp->cfg_users--;
	}

	return 0;
}