Ejemplo n.º 1
0
/* File Open */
static int fm_v4l2_fops_open(struct file *file)
{
	int ret;

	FMDRV_API_START();

	/* Don't allow multiple open */
	if (radio_disconnected) {
		FM_DRV_ERR("FM device is already opened\n");
		FMDRV_API_EXIT(-EBUSY);
		return -EBUSY;
	}

	/* Request FM Core to link with FM ST */
	ret = fm_core_setup_transport();
	if (ret) {
		FM_DRV_ERR("Unable to setup FM Core transport");
		FMDRV_API_EXIT(ret);
		return ret;
	}
	/* Initialize FM Core */
	ret = fm_core_prepare();
	if (ret) {
		FM_DRV_ERR("Unable to prepare FM CORE");
		FMDRV_API_EXIT(ret);
		return ret;
	}

	FM_DRV_DBG("Load FM RX firmware..");
	/* By default load FM RX firmware */
	ret = fm_core_mode_set(FM_MODE_RX);
	if (ret) {
		FM_DRV_ERR("Unable to load FM RX firmware");
		FMDRV_API_EXIT(ret);
		return ret;
	}
	radio_disconnected = 1;
	FM_DRV_DBG("FM CORE is ready");

	FMDRV_API_EXIT(0);
	return 0;
}
Ejemplo n.º 2
0
/* File Release */
static int fm_v4l2_fops_release(struct file *file)
{
	int ret;

	FMDRV_API_START();

	if (!radio_disconnected) {
		FM_DRV_DBG("FM device already closed,close called again?");
		FMDRV_API_EXIT(0);
		return 0;
	}

	FM_DRV_DBG("Turning off..");
	ret = fm_core_mode_set(FM_MODE_OFF);
	if (ret) {
		FM_DRV_ERR("Unable to turn off the chip");
		FMDRV_API_EXIT(ret);
		return ret;
	}
	/* Request FM Core to unlink from ST driver */
	ret = fm_core_release();
	if (ret) {
		FM_DRV_ERR("FM CORE release failed");
		FMDRV_API_EXIT(ret);
		return ret;
	}

	/* Release FM Core transport */
	ret = fm_core_release_transport();
	if (ret) {
		FM_DRV_ERR("Unable to setup FM Core transport");
		FMDRV_API_EXIT(ret);
		return ret;
	}
	radio_disconnected = 0;
	FM_DRV_DBG("FM CORE released successfully");

	FMDRV_API_EXIT(0);
	return 0;
}
Ejemplo n.º 3
0
/* Called from FM Core and FM Char device interface to claim
 * FM ST. Who ever comes first, ownership of FM ST will be
 * given to them.
 */
int fm_st_claim(void)
{
	FMDRV_API_START();

	/* Give ownership of FM ST to first caller */
	if (is_fm_st_claimed == FM_ST_NOT_CLAIMED) {
		is_fm_st_claimed = FM_ST_CLAIMED;

		FMDRV_API_EXIT(FM_ST_SUCCESS);
		return FM_ST_SUCCESS;
	}

	FM_DRV_DBG("FM ST claimed already");

	FMDRV_API_EXIT(FM_ST_FAILED);
	return FM_ST_FAILED;
}
Ejemplo n.º 4
0
/* Write RDS data */
static ssize_t fm_v4l2_fops_write(struct file *file, const char __user * buf,
				  size_t count, loff_t *ppos)
{
	struct tx_rds rds;
	int ret;
	FMDRV_API_START();

	ret = copy_from_user(&rds, buf, sizeof(rds));
	FM_DRV_DBG("(%d)type: %d, text %s, af %d",
		   ret, rds.text_type, rds.text, rds.af_freq);

	fm_core_tx_set_radio_text(rds.text, rds.text_type);
	fm_core_tx_set_af(rds.af_freq);

	FMDRV_API_EXIT(0);
	return 0;
}
Ejemplo n.º 5
0
/* Called from V4L2 RADIO open function (fm_fops_open()) to
 * register FM driver with Shared Transport
 */
int fm_st_register(struct sk_buff_head *rx_q, struct tasklet_struct *rx_task)
{
	static struct st_proto_s fm_st_proto;
	unsigned long timeleft;
	int ret;

	ret = 0;

	FMDRV_API_START();

	/* Populate FM driver info required by ST */
	memset(&fm_st_proto, 0, sizeof(fm_st_proto));

	/* FM driver ID */
	fm_st_proto.channelid = 8;

	/* Receive function which called from ST */
	fm_st_proto.recv = fm_st_receive;

	/* Packet match function may used in future */
	fm_st_proto.match_packet = NULL;

	/* Callback to be called when registration is pending */
	fm_st_proto.reg_complete_cb = fm_st_registration_completion_cb;

	fm_st_proto.max_frame_size = 255;
	fm_st_proto.header_size = 3;
	fm_st_proto.length_offset = 1;
	fm_st_proto.length_size = 2;	
	fm_st_proto.gpio_id = ST_GPIO_FM;


	/* Register with ST layer */
	ret = st_register(&fm_st_proto);
	if (ret == ST_ERR_PENDING) {
		/* Prepare wait-for-completion handler data structures.
		 * Needed to syncronize this and
		 * fm_st_registration_completion_cb() functions.
		 */
		init_completion(&wait_for_fmdrv_reg_completion);

		/* Reset ST registration callback status flag. This value
		 * will be updated in fm_st_registration_completion_cb()
		 * function whenever it is called from ST driver.
		 */
		streg_cbdata = -EINPROGRESS;

		/* ST is busy with other protocol registration (may be busy with
		 * firmware download). So, wait till the registration callback
		 * (passed as a argument to st_register() function) getting
		 * called from ST.
		 */
		FM_DRV_DBG(" %s waiting for reg completion signal from ST",
			   __func__);

		timeleft =
		    wait_for_completion_timeout(&wait_for_fmdrv_reg_completion,
						FM_ST_REGISTER_TIMEOUT);
		if (!timeleft) {
			FM_DRV_ERR("Timeout(%d sec), didn't get reg"
				   "completion signal from ST",
				   jiffies_to_msecs(FM_ST_REGISTER_TIMEOUT) /
				   1000);
			FMDRV_API_EXIT(-ETIMEDOUT);
			return -ETIMEDOUT;
		}

		/* Is ST registration callback called with ERROR value? */
		if (streg_cbdata != 0) {
			FM_DRV_ERR("ST reg completion CB called with invalid"
				   "status %d", streg_cbdata);
			FMDRV_API_EXIT(-EAGAIN);
			return -EAGAIN;
		}
		ret = 0;
	} else if (ret == ST_ERR_FAILURE) {
		FM_DRV_ERR("st_register failed %d", ret);
		FMDRV_API_EXIT(-EAGAIN);
		return -EAGAIN;
	}

	/* Store Rx Q and Rx tasklet pointers. This pointers should
	 * already initialized by caller
	 */
	g_rx_task = rx_task;
	g_rx_q = rx_q;

	FMDRV_API_EXIT(ret);
	return ret;
}