Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fe3e0c09 authored by Prateek Raj Singh's avatar Prateek Raj Singh Committed by Gerrit - the friendly Code Review server
Browse files

FM: Fix for no sound issue in FM Audio



Updated mutex_lock during tune/seek operation

Change-Id: I699f0a208ea7f9009226ebff962a5ef38f197d73
Signed-off-by: default avatarPrateek Raj Singh <pratsing@codeaurora.org>
parent ef2d7b04
Loading
Loading
Loading
Loading
+63 −29
Original line number Diff line number Diff line
@@ -315,11 +315,13 @@ void rtc6226_scan(struct work_struct *work)
	u8 factor;
	int retval = 0;
	int i, rssi;
	unsigned long time;

	FMDBG("%s enter\n", __func__);

	radio = container_of(work, struct rtc6226_device, work_scan.work);

	mutex_lock(&radio->lock);
	retval = rtc6226_get_freq(radio, &current_freq_khz);
	if (retval < 0) {
		FMDERR("%s fail to get freq\n", __func__);
@@ -333,10 +335,14 @@ void rtc6226_scan(struct work_struct *work)
	if (retval < 0)
		goto seek_tune_fail;
	/* wait for tune to complete. */
	if (!wait_for_completion_timeout(&radio->completion,
				msecs_to_jiffies(TUNE_TIMEOUT_MSEC))) {
	mutex_unlock(&radio->lock);
	time = wait_for_completion_timeout(&radio->completion,
			msecs_to_jiffies(TUNE_TIMEOUT_MSEC));
	mutex_lock(&radio->lock);
	if (!time) {
		FMDERR("In %s, didn't receive STC for tune\n", __func__);
		rtc6226_q_event(radio, RTC6226_EVT_ERROR);
		mutex_unlock(&radio->lock);
		return;
	}

@@ -351,6 +357,7 @@ void rtc6226_scan(struct work_struct *work)
		} else if (radio->mode != FM_RECV) {
			FMDERR("%s: FM is not in proper state\n", __func__);
			rtc6226_q_event(radio, RTC6226_EVT_ERROR);
			mutex_unlock(&radio->lock);
			return;
		}

@@ -360,8 +367,11 @@ void rtc6226_scan(struct work_struct *work)
			goto seek_tune_fail;
		}
			/* wait for seek to complete */
		if (!wait_for_completion_timeout(&radio->completion,
					msecs_to_jiffies(SEEK_TIMEOUT_MSEC))) {
		mutex_unlock(&radio->lock);
		time = wait_for_completion_timeout(&radio->completion,
				msecs_to_jiffies(SEEK_TIMEOUT_MSEC));
		mutex_lock(&radio->lock);
		if (!time) {
			FMDERR("%s:timeout didn't receive STC for seek\n",
						__func__);
			rtc6226_get_all_registers(radio);
@@ -370,6 +380,7 @@ void rtc6226_scan(struct work_struct *work)
					radio->registers[i]);
			/* FM is not correct state or scan is cancelled */
			rtc6226_q_event(radio, RTC6226_EVT_ERROR);
			mutex_unlock(&radio->lock);
			return;
		} else
			FMDERR("%s: received STC for seek\n", __func__);
@@ -406,6 +417,7 @@ void rtc6226_scan(struct work_struct *work)
		} else if (radio->mode != FM_RECV) {
			FMDERR("%s: FM is not in proper state\n", __func__);
			rtc6226_q_event(radio, RTC6226_EVT_ERROR);
			mutex_unlock(&radio->lock);
			return;
		}
		FMDBG("%s update search list %d\n", __func__, next_freq_khz);
@@ -420,7 +432,6 @@ void rtc6226_scan(struct work_struct *work)
					&& rssi >= radio->rssi_th) {
			rtc6226_update_search_list(radio, next_freq_khz);
		}

		FMDBG("%s : STATUS=0x%4.4hx\n", __func__,
				radio->registers[STATUS]);
		if (radio->registers[STATUS] & STATUS_SF ||
@@ -455,10 +466,14 @@ void rtc6226_scan(struct work_struct *work)
				FMDERR("%s seek fail %d\n", __func__, retval);
				goto seek_tune_fail;
			}
			if (!wait_for_completion_timeout(&radio->completion,
					msecs_to_jiffies(SEEK_TIMEOUT_MSEC))) {
			mutex_unlock(&radio->lock);
			time = wait_for_completion_timeout(&radio->completion,
					msecs_to_jiffies(SEEK_TIMEOUT_MSEC));
			mutex_lock(&radio->lock);
			if (!time) {
				FMDERR("timeout didn't receive STC for seek\n");
				rtc6226_q_event(radio, RTC6226_EVT_ERROR);
				mutex_unlock(&radio->lock);
				return;
			} else {
				FMDERR("%s: received STC for seek\n", __func__);
@@ -514,8 +529,11 @@ void rtc6226_scan(struct work_struct *work)
		FMDERR("%s: Tune to orig freq failed with error %d\n",
				__func__, retval);
	else {
		if (!wait_for_completion_timeout(&radio->completion,
			msecs_to_jiffies(TUNE_TIMEOUT_MSEC)))
		mutex_unlock(&radio->lock);
		time = wait_for_completion_timeout(&radio->completion,
				msecs_to_jiffies(TUNE_TIMEOUT_MSEC));
		mutex_lock(&radio->lock);
		if (!time)
			FMDERR("%s: didn't receive STD for tune\n", __func__);
		else
			FMDERR("%s: received STD for tune\n", __func__);
@@ -526,6 +544,7 @@ void rtc6226_scan(struct work_struct *work)
	rtc6226_q_event(radio, RTC6226_EVT_TUNE_SUCC);
	radio->seek_tune_status = NO_SEEK_TUNE_PENDING;
	FMDERR("%s seek cancelled %d\n", __func__, retval);
	mutex_unlock(&radio->lock);
	return;

}
@@ -535,14 +554,12 @@ int rtc6226_cancel_seek(struct rtc6226_device *radio)
	int retval = 0;

	FMDBG("%s enter\n", __func__);
	mutex_lock(&radio->lock);

	/* stop seeking */
	radio->registers[SEEKCFG1] &= ~SEEKCFG1_CSR0_SEEK;
	retval = rtc6226_set_register(radio, SEEKCFG1);
	complete(&radio->completion);

	mutex_unlock(&radio->lock);
	radio->is_search_cancelled = true;
	if (radio->g_search_mode == SEEK)
		rtc6226_q_event(radio, RTC6226_EVT_SEEK_COMPLETE);
@@ -557,6 +574,24 @@ void rtc6226_search(struct rtc6226_device *radio, bool on)

	current_freq_khz = radio->tuned_freq_khz;

	FMDBG("%s rtc6226_power_up1: DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
		__func__,
		radio->registers[DEVICEID], radio->registers[CHIPID]);
	FMDBG("%s rtc6226_power_up2: Reg2=0x%4.4hx Reg3=0x%4.4hx\n", __func__,
		radio->registers[MPXCFG], radio->registers[CHANNEL]);
	FMDBG("%s rtc6226_power_up3: Reg4=0x%4.4hx Reg5=0x%4.4hx\n", __func__,
		radio->registers[SYSCFG], radio->registers[SEEKCFG1]);
	FMDBG("%s rtc6226_power_up4: Reg6=0x%4.4hx Reg7=0x%4.4hx\n", __func__,
		radio->registers[POWERCFG], radio->registers[PADCFG]);
	FMDBG("%s rtc6226_power_up5: Reg8=0x%4.4hx Reg9=0x%4.4hx\n", __func__,
		radio->registers[8], radio->registers[9]);
	FMDBG("%s rtc6226_power_up6: regA=0x%4.4hx RegB=0x%4.4hx\n", __func__,
		radio->registers[10], radio->registers[11]);
	FMDBG("%s rtc6226_power_up7: regC=0x%4.4hx RegD=0x%4.4hx\n", __func__,
		radio->registers[12], radio->registers[13]);
	FMDBG("%s rtc6226_power_up8: regE=0x%4.4hx RegF=0x%4.4hx\n", __func__,
		radio->registers[14], radio->registers[15]);

	if (on) {
		FMDBG("%s: Queuing the work onto scan work q\n", __func__);
		queue_delayed_work(radio->wqueue_scan, &radio->work_scan,
@@ -695,12 +730,10 @@ static void rtc6226_get_rds(struct rtc6226_device *radio)
{
	int retval = 0;

	mutex_lock(&radio->lock);
	retval = rtc6226_get_all_registers(radio);

	if (retval < 0) {
		FMDERR("%s read fail%d\n", __func__, retval);
		mutex_unlock(&radio->lock);
		return;
	}
	radio->block[0] = radio->registers[BA_DATA];
@@ -712,7 +745,6 @@ static void rtc6226_get_rds(struct rtc6226_device *radio)
	radio->bler[1] = (radio->registers[RSSI] & RSSI_RDS_BB_ERRS) >> 12;
	radio->bler[2] = (radio->registers[RSSI] & RSSI_RDS_BC_ERRS) >> 10;
	radio->bler[3] = (radio->registers[RSSI] & RSSI_RDS_BD_ERRS) >> 8;
	mutex_unlock(&radio->lock);
}

static void rtc6226_pi_check(struct rtc6226_device *radio, u16 current_pi)
@@ -1312,7 +1344,7 @@ void rtc6226_rds_handler(struct work_struct *worker)
	}

	FMDBG("%s enter\n", __func__);

	mutex_lock(&radio->lock);
	rtc6226_get_rds(radio);

	if (radio->bler[0] < CORRECTED_THREE_TO_FIVE)
@@ -1323,6 +1355,7 @@ void rtc6226_rds_handler(struct work_struct *worker)
		FMDBG("%s grp_type = %d\n", __func__, grp_type);
	} else {
		/* invalid data case */
		mutex_unlock(&radio->lock);
		return;
	}
	if (grp_type & 0x01)
@@ -1382,6 +1415,8 @@ void rtc6226_rds_handler(struct work_struct *worker)
		rtc6226_rt_plus(radio);
	else if (radio->ert_carrier && (grp_type == radio->ert_carrier))
		rtc6226_buff_ert(radio);

	mutex_unlock(&radio->lock);
}

/*
@@ -1404,7 +1439,6 @@ int rtc6226_rds_on(struct rtc6226_device *radio)

int rtc6226_reset_rds_data(struct rtc6226_device *radio)
{
	mutex_lock(&radio->lock);
	radio->pi = 0;
	/* reset PS bufferes */
	memset(radio->ps_display, 0, sizeof(radio->ps_display));
@@ -1419,7 +1453,6 @@ int rtc6226_reset_rds_data(struct rtc6226_device *radio)
	radio->wr_index = 0;
	radio->rd_index = 0;
	memset(radio->buffer, 0, radio->buf_size);
	mutex_unlock(&radio->lock);

	return 0;
}
@@ -1445,12 +1478,10 @@ int rtc6226_power_down(struct rtc6226_device *radio)

	FMDBG("%s enter\n", __func__);

	mutex_lock(&radio->lock);
		/* stop radio */
	retval = rtc6226_stop(radio);

	//rtc6226_disable_irq(radio);
	mutex_unlock(&radio->lock);
	FMDBG("%s exit %d\n", __func__, retval);

	return retval;
@@ -1460,8 +1491,6 @@ int rtc6226_power_up(struct rtc6226_device *radio)
{
	int retval = 0;

	mutex_lock(&radio->lock);

	FMDBG("%s enter\n", __func__);

	/* start radio */
@@ -1535,7 +1564,6 @@ int rtc6226_power_up(struct rtc6226_device *radio)

done:
	FMDBG("%s exit %d\n", __func__, retval);
	mutex_unlock(&radio->lock);
	return retval;
}

@@ -1826,6 +1854,7 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv,
	FMDBG("%s enter, ctrl->id: %x, value:%d\n", __func__,
		ctrl->id, ctrl->value);

	mutex_lock(&radio->lock);
	switch (ctrl->id) {
	case V4L2_CID_PRIVATE_RTC6226_STATE:
		if (ctrl->value == FM_RECV) {
@@ -2086,6 +2115,7 @@ int rtc6226_vidioc_s_ctrl(struct file *file, void *priv,

end:
	FMDBG("%s exit id: %x , ret: %d\n", __func__, ctrl->id, retval);
	mutex_unlock(&radio->lock);

	return retval;
}
@@ -2116,7 +2146,7 @@ static int rtc6226_vidioc_g_tuner(struct file *file, void *priv,
	int retval = 0;

	FMDBG("%s enter\n", __func__);

	mutex_lock(&radio->lock);
	if (tuner->index != 0) {
		retval = -EINVAL;
		goto done;
@@ -2164,7 +2194,7 @@ static int rtc6226_vidioc_g_tuner(struct file *file, void *priv,

done:
	FMDBG("%s exit %d\n", __func__, retval);

	mutex_unlock(&radio->lock);
	return retval;
}

@@ -2181,7 +2211,7 @@ static int rtc6226_vidioc_s_tuner(struct file *file, void *priv,
	u16 top_freq;

	FMDBG("%s entry\n", __func__);

	mutex_lock(&radio->lock);
	if (tuner->index != 0) {
		FMDBG("%s index :%d\n", __func__, tuner->index);
		goto done;
@@ -2226,6 +2256,7 @@ static int rtc6226_vidioc_s_tuner(struct file *file, void *priv,
		radio->recv_conf.band_low_limit = bottom_freq;
done:
	FMDBG("%s exit %d\n", __func__, retval);
	mutex_unlock(&radio->lock);
	return retval;
}

@@ -2241,7 +2272,7 @@ static int rtc6226_vidioc_g_frequency(struct file *file, void *priv,
	unsigned int frq;

	FMDBG("%s enter freq %d\n", __func__, freq->frequency);

	mutex_lock(&radio->lock);
	freq->type = V4L2_TUNER_RADIO;
	retval = rtc6226_get_freq(radio, &frq);
	freq->frequency = frq * TUNE_PARAM;
@@ -2250,7 +2281,7 @@ static int rtc6226_vidioc_g_frequency(struct file *file, void *priv,

	if (retval < 0)
		FMDERR(" %s get frequency failed with %d\n", __func__, retval);

	mutex_unlock(&radio->lock);
	return retval;
}

@@ -2274,13 +2305,14 @@ static int rtc6226_vidioc_s_frequency(struct file *file, void *priv,
		return -EINVAL;
	f = (freq->frequency)/TUNE_PARAM;

	mutex_lock(&radio->lock);
	radio->seek_tune_status = TUNE_PENDING;
	retval = rtc6226_set_freq(radio, f);
	if (retval < 0)
		FMDERR("%s set frequency failed with %d\n", __func__, retval);
	else
		radio->tuned_freq_khz = f;

	mutex_unlock(&radio->lock);
	return retval;
}

@@ -2299,6 +2331,7 @@ static int rtc6226_vidioc_s_hw_freq_seek(struct file *file, void *priv,
	if (file->f_flags & O_NONBLOCK)
		return -EWOULDBLOCK;

	mutex_lock(&radio->lock);
	radio->is_search_cancelled = false;

	/* Disable the rds before seek */
@@ -2332,6 +2365,7 @@ static int rtc6226_vidioc_s_hw_freq_seek(struct file *file, void *priv,
				__func__, radio->g_search_mode);
	}
	FMDBG("%s exit %d\n", __func__, retval);
	mutex_unlock(&radio->lock);
	return retval;
}

+11 −5
Original line number Diff line number Diff line
@@ -229,7 +229,7 @@ static void rtc6226_i2c_interrupt_handler(struct rtc6226_device *radio)
	unsigned short current_chan;

	FMDBG("%s enter\n", __func__);

	mutex_lock(&radio->lock);
	/* check Seek/Tune Complete */
	retval = rtc6226_get_register(radio, STATUS);
	if (retval < 0) {
@@ -267,11 +267,13 @@ static void rtc6226_i2c_interrupt_handler(struct rtc6226_device *radio)
			FMDBG("posting RICHWAVE_EVT_TUNE_SUCC event\n");
			rtc6226_q_event(radio, RTC6226_EVT_TUNE_SUCC);
			radio->seek_tune_status = NO_SEEK_TUNE_PENDING;
		} else if (radio->seek_tune_status == TUNE_PENDING) {
		} else if ((radio->seek_tune_status == TUNE_PENDING) ||
			(radio->g_search_mode != SCAN)) {
			FMDBG("posting RICHWAVE_EVT_TUNE_SUCC event\n");
			rtc6226_q_event(radio, RTC6226_EVT_TUNE_SUCC);
			radio->seek_tune_status = NO_SEEK_TUNE_PENDING;
		} else if (radio->seek_tune_status == SCAN_PENDING) {
		} else if ((radio->seek_tune_status == SCAN_PENDING) ||
			(radio->g_search_mode == SCAN)) {
			/* when scan is pending and STC int is set, signal
			 * so that scan can proceed
			 */
@@ -279,7 +281,8 @@ static void rtc6226_i2c_interrupt_handler(struct rtc6226_device *radio)
			complete(&radio->completion);
		}
		FMDBG("%s Seek/Tune done\n", __func__);
	} else {
	} else if ((radio->seek_tune_status != TUNE_PENDING) &&
				(radio->seek_tune_status != SCAN_PENDING)) {
		/* Check RDS data after tune/seek interrupt finished
		 * Update RDS registers
		 */
@@ -302,6 +305,7 @@ static void rtc6226_i2c_interrupt_handler(struct rtc6226_device *radio)
		}
	}
end:
	mutex_unlock(&radio->lock);
	FMDBG("%s exit :%d\n", __func__, retval);
}

@@ -527,7 +531,7 @@ int rtc6226_fops_open(struct file *file)
	struct rtc6226_device *radio = video_drvdata(file);
	int retval;

	FMDBG("%s enter user num = %d\n", __func__, radio->users);
	FMDBG("%s enter user num = %d\n", __func__, atomic_read(&radio->users));
	if (atomic_inc_return(&radio->users) != 1) {
		FMDERR("Device already in use. Try again later\n");
		atomic_dec(&radio->users);
@@ -570,6 +574,7 @@ int rtc6226_fops_release(struct file *file)
	int retval = 0;

	FMDBG("%s : Exit\n", __func__);
	mutex_lock(&radio->lock);
	if (radio->mode != FM_OFF) {
		rtc6226_power_down(radio);
		radio->mode = FM_OFF;
@@ -579,6 +584,7 @@ int rtc6226_fops_release(struct file *file)
	retval = rtc6226_fm_power_cfg(radio, TURNING_OFF);
	if (retval < 0)
		FMDERR("%s: failed to apply voltage\n", __func__);
	mutex_unlock(&radio->lock);
	return retval;
}