Example #1
0
static void sec_jack_det_work_func(struct work_struct *work)
{
	struct sec_jack_info *hi =
		container_of(work, struct sec_jack_info, det_work);

	struct sec_jack_platform_data *pdata = hi->pdata;
	int time_left_ms = DET_CHECK_TIME_MS;

	pr_debug(MODULE_NAME "%s\n", __func__);

	/* threaded irq can sleep */
	wake_lock_timeout(&hi->det_wake_lock, WAKE_LOCK_TIME);

#ifdef CONFIG_MACH_JAGUAR
	if ((hi->cur_jack_type == SEC_HEADSET_4POLE) && sendkey_irq_progress) {
		pr_info(MODULE_NAME "%s / 120ms Delay\n", __func__);
		usleep_range(120000, 120000);

	} else {
		pr_info(MODULE_NAME "%s / No Delay\n", __func__);
		sendkey_irq_progress = false;
	}
#endif

	/* debounce headset jack.  don't try to determine the type of
	 * headset until the detect state is true for a while.
	 */
	while (time_left_ms > 0) {
		if (!pdata->get_det_jack_state()) {
			/* jack not detected. */
			handle_jack_not_inserted(hi);
			return;
		}
		usleep_range(10000, 10000);
		time_left_ms -= 10;
	}

#if defined(CONFIG_SAMSUNG_JACK_GNDLDET)
	/* G plus L Detection */
	if (!hi->pdata->get_l_jack_state())
		return;
#endif
	/* set mic bias to enable adc */
	pdata->set_micbias_state(true);

	/* to reduce noise in earjack when attaching */
	/* msleep(200); */

	/* jack presence was detected the whole time, figure out which type */
	determine_jack_type(hi);

	return;
}
Example #2
0
static void sec_jack_det_work_func(struct work_struct *work)
{
	struct sec_jack_info *hi =
		container_of(work, struct sec_jack_info, det_work);

	struct sec_jack_platform_data *pdata = hi->pdata;
	int time_left_ms = DET_CHECK_TIME_MS;
	int jack_state = 0;

	pr_debug(MODULE_NAME "%s\n", __func__);

	/* threaded irq can sleep */
	wake_lock_timeout(&hi->det_wake_lock, WAKE_LOCK_TIME);

	/* debounce headset jack.  don't try to determine the type of
	 * headset until the detect state is true for a while.
	 */
	while (time_left_ms > 0) {
		jack_state = pdata->get_det_jack_state();
		if (!jack_state) {
			pr_err("%s : err det jack state %d\n",
				__func__, jack_state);
			/* jack not detected. */
			handle_jack_not_inserted(hi);
			return;
		}
		usleep_range(10000, 10000);
		time_left_ms -= 10;
	}

	/* set mic bias to enable adc */
	pdata->set_micbias_state(true);

	/* to reduce noise in earjack when attaching */
	/* msleep(200); */

	/* jack presence was detected the whole time, figure out which type */
	determine_jack_type(hi);

	return;
}
Example #3
0
static void determine_jack_type(struct sec_jack_info *hi)
{
	struct sec_jack_zone *zones = hi->pdata->zones;
	struct sec_jack_platform_data *pd = hi->pdata;
	int size = hi->pdata->num_zones;
	int count[MAX_ZONE_LIMIT] = {0};
	int adc;
	int i;

	struct adc_queue *adc_q = init_adc_queue();
#if defined (CONFIG_MACH_MELIUS_CHN_CTC)
	if (nv_hw_revision > 7 || nv_hw_revision < 2)
		zones = pd->zones_rev08;
#elif defined (CONFIG_MACH_SERRANO_ATT) || defined(CONFIG_MACH_SERRANO_VZW) || defined(CONFIG_MACH_SERRANO_USC) || defined(CONFIG_MACH_SERRANO_LRA)
	if (system_rev > 2)
		zones = pd->zones_rev03;
#endif
	while (pd->get_det_jack_state()) {
#ifdef CONFIG_SAMSUNG_JACK_ADC_SCALE3
		adc = pd->get_ear_adc_value();
#else
		adc = pd->get_adc_value();
#endif
		if (adc < 0)
			break;

		add_adc_queue(adc_q, adc);

		/* determine the type of headset based on the
		 * adc value.  An adc value can fall in various
		 * ranges or zones.  Within some ranges, the type
		 * can be returned immediately.  Within others, the
		 * value is considered unstable and we need to sample
		 * a few more types (up to the limit determined by
		 * the range) before we return the type for that range.
		 */
		for (i = 0; i < size; i++) {
			if (adc <= zones[i].adc_high) {
				if (++count[i] > zones[i].check_count) {
					print_adc_queue(adc_q);
					pr_debug(MODULE_NAME "determine_jack_type %d, %d, %d\n",
						zones[i].adc_high, count[i],
						zones[i].check_count);
#if defined(CONFIG_SAMSUNG_JACK_GNDLDET)
					/* G plus L Detection */
					if (!hi->pdata->get_gnd_jack_state()) {
						pr_err("%s : err 2nd det jack state\n",
							__func__);
						handle_jack_not_inserted(hi);
						recheck_jack = false;
						return;
					}
#else
					if (recheck_jack == true && i == 3) {
						pr_err(MODULE_NAME "something wrong connectoin!\n");
						handle_jack_not_inserted(hi);
						recheck_jack = false;
						return;
					}
#endif
					sec_jack_set_type(hi,
							zones[i].jack_type);
					/* mic_bias remains enabled
					 * in race condition.
					 */
					if (hi->cur_jack_type !=
							SEC_HEADSET_4POLE) {
						pd->set_micbias_state(false);
						pr_info(MODULE_NAME "forced mic_bias disable\n");
					}
					recheck_jack = false;
					return;
				}
#if defined CONFIG_MACH_GOLDEN
				msleep(zones[i].delay_ms);
#else
				usleep_range(zones[i].delay_ms*1000, zones[i].delay_ms*1000);
#endif
				break;
			}
		}
	}
	/* jack removed before detection complete */
	recheck_jack = false;
	pr_err("%s : err det jack state\n", __func__);
	print_adc_queue(adc_q);
	handle_jack_not_inserted(hi);
}
Example #4
0
static void determine_jack_type(struct sec_jack_info *hi)
{
	struct sec_jack_zone *zones = hi->pdata->zones;
	int size = hi->pdata->num_zones;
	int count[MAX_ZONE_LIMIT] = {0};
	int adc;
	int i;

	while (hi->pdata->get_det_jack_state()) {
		adc = hi->pdata->get_adc_value();
		pr_info(MODULE_NAME "determine_jack_type adc = %d\n", adc);

		/* determine the type of headset based on the
		 * adc value.  An adc value can fall in various
		 * ranges or zones.  Within some ranges, the type
		 * can be returned immediately.  Within others, the
		 * value is considered unstable and we need to sample
		 * a few more types (up to the limit determined by
		 * the range) before we return the type for that range.
		 */
		for (i = 0; i < size; i++) {
			if (adc <= zones[i].adc_high) {
				if (++count[i] > zones[i].check_count) {
					pr_debug(MODULE_NAME "determine_jack_type %d, %d, %d\n",
						zones[i].adc_high, count[i],
						zones[i].check_count);
#ifndef CONFIG_MACH_JAGUAR
					if (recheck_jack == true && i == 3) {
#else
					if (recheck_jack == true && i == 5) {
#endif
						pr_err(MODULE_NAME "something wrong connectoin!\n");
						handle_jack_not_inserted(hi);
						recheck_jack = false;
						return;
					}

					sec_jack_set_type(hi,
							zones[i].jack_type);
					/* mic_bias remains enabled
					 * in race condition.
					 */
					if (hi->cur_jack_type !=
							SEC_HEADSET_4POLE) {
						hi->pdata->set_micbias_state(false);
						pr_info(MODULE_NAME "forced mic_bias disable\n");
					}
					recheck_jack = false;
					return;
				}
				msleep(zones[i].delay_ms);
				break;
			}
		}
	}
	/* jack removed before detection complete */
	recheck_jack = false;
	handle_jack_not_inserted(hi);
}

#ifdef SUPPORT_PBA
static ssize_t  key_state_onoff_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct sec_jack_info *hi = dev_get_drvdata(dev);
#ifdef CONFIG_MACH_JAGUAR
	struct sec_jack_platform_data *pdata = hi->pdata;
#endif
	int value = 0;
#ifdef CONFIG_MACH_JAGUAR
	int send_key_state = 0;
#endif
#ifndef CONFIG_MACH_JAGUAR
	if (hi->send_key_pressed != true)
		value = 0;
	else
		value = 1;
#else
	send_key_state = pdata->get_send_key_state();
	pr_info(MODULE_NAME "%s : cur_jack_type=%d, send_key_state=%d.\n",
			__func__, hi->cur_jack_type, send_key_state);
	if ((hi->cur_jack_type != SEC_HEADSET_4POLE) ||
			(send_key_state != true))
		value = 0;
	else
		value = 1;
#endif
	return sprintf(buf, "%d\n", value);
}

static DEVICE_ATTR(key_state, 0664 , key_state_onoff_show,
		NULL);

static ssize_t  earjack_state_onoff_show(struct device *dev,
		struct device_attribute *attr, char *buf)

{
	struct sec_jack_info *hi = dev_get_drvdata(dev);
	int value = 0;

	if (hi->cur_jack_type == SEC_HEADSET_4POLE)
		value = 1;
	else
		value = 0;
	return sprintf(buf, "%d\n", value);
}

static DEVICE_ATTR(state, 0664 , earjack_state_onoff_show,
		NULL);

static ssize_t select_jack_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	pr_info("%s : operate nothing\n", __func__);
	return 0;
}