Commit 0830be3f authored by Joonyoung Shim's avatar Joonyoung Shim Committed by Mauro Carvalho Chehab
Browse files

[media] radio-si470x: support seek and tune interrupt enable



Currently we use busy waiting to seek and tune, it can replace to
interrupt way. SI470X I2C driver supports interrupt way to week and tune
via this patch.

Signed-off-by: default avatarJoonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent cc73b4b5
Loading
Loading
Loading
Loading
+42 −18
Original line number Diff line number Diff line
@@ -174,6 +174,16 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
	if (retval < 0)
		goto done;

	/* currently I2C driver only uses interrupt way to tune */
	if (radio->stci_enabled) {
		INIT_COMPLETION(radio->completion);

		/* wait till tune operation has completed */
		retval = wait_for_completion_timeout(&radio->completion,
				msecs_to_jiffies(tune_timeout));
		if (!retval)
			timed_out = true;
	} else {
		/* wait till tune operation has completed */
		timeout = jiffies + msecs_to_jiffies(tune_timeout);
		do {
@@ -181,8 +191,10 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
			if (retval < 0)
				goto stop;
			timed_out = time_after(jiffies, timeout);
	} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
		(!timed_out));
		} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
				&& (!timed_out));
	}

	if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
		dev_warn(&radio->videodev->dev, "tune does not complete\n");
	if (timed_out)
@@ -310,6 +322,16 @@ static int si470x_set_seek(struct si470x_device *radio,
	if (retval < 0)
		goto done;

	/* currently I2C driver only uses interrupt way to seek */
	if (radio->stci_enabled) {
		INIT_COMPLETION(radio->completion);

		/* wait till seek operation has completed */
		retval = wait_for_completion_timeout(&radio->completion,
				msecs_to_jiffies(seek_timeout));
		if (!retval)
			timed_out = true;
	} else {
		/* wait till seek operation has completed */
		timeout = jiffies + msecs_to_jiffies(seek_timeout);
		do {
@@ -317,8 +339,10 @@ static int si470x_set_seek(struct si470x_device *radio,
			if (retval < 0)
				goto stop;
			timed_out = time_after(jiffies, timeout);
	} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
		(!timed_out));
		} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
				&& (!timed_out));
	}

	if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
		dev_warn(&radio->videodev->dev, "seek does not complete\n");
	if (radio->registers[STATUSRSSI] & STATUSRSSI_SF)
+15 −2
Original line number Diff line number Diff line
@@ -197,8 +197,9 @@ int si470x_fops_open(struct file *file)
		if (retval < 0)
			goto done;

		/* enable RDS interrupt */
		/* enable RDS / STC interrupt */
		radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN;
		radio->registers[SYSCONFIG1] |= SYSCONFIG1_STCIEN;
		radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2;
		radio->registers[SYSCONFIG1] |= 0x1 << 2;
		retval = si470x_set_register(radio, SYSCONFIG1);
@@ -274,12 +275,20 @@ static void si470x_i2c_interrupt_work(struct work_struct *work)
	unsigned char tmpbuf[3];
	int retval = 0;

	/* check Seek/Tune Complete */
	retval = si470x_get_register(radio, STATUSRSSI);
	if (retval < 0)
		return;

	if (radio->registers[STATUSRSSI] & STATUSRSSI_STC)
		complete(&radio->completion);

	/* safety checks */
	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
		return;

	/* Update RDS registers */
	for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) {
	for (regnr = 1; regnr < RDS_REGISTER_NUM; regnr++) {
		retval = si470x_get_register(radio, STATUSRSSI + regnr);
		if (retval < 0)
			return;
@@ -441,6 +450,10 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
	radio->rd_index = 0;
	init_waitqueue_head(&radio->read_queue);

	/* mark Seek/Tune Complete Interrupt enabled */
	radio->stci_enabled = true;
	init_completion(&radio->completion);

	retval = request_irq(client->irq, si470x_i2c_interrupt,
			IRQF_TRIGGER_FALLING, DRIVER_NAME, radio);
	if (retval) {
+3 −0
Original line number Diff line number Diff line
@@ -158,6 +158,9 @@ struct si470x_device {
	unsigned int rd_index;
	unsigned int wr_index;

	struct completion completion;
	bool stci_enabled;		/* Seek/Tune Complete Interrupt */

#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
	/* reference to USB and video device */
	struct usb_device *usbdev;