static void max97236_jack_plugged(struct max97236_priv *max97236)
{
	unsigned int status_reg[3] = {0, 0, 0};
	int retries = M97236_DEFAULT_RETRIES;
	int force_value = 0;
	int count;
	wake_lock(&wakelock);
	/* Check for spurious interrupt */
	if (!max97236_jacksw_active(max97236)) {
		max97236_jack_event(max97236);
		goto max97236_jack_plugged_30;
	}
#if 1
	/* Start debounce while periodically verifying jack presence */
	for (count = 0; count < 24; count++) {
		msleep(40);
		if (!max97236_jacksw_active(max97236)) {
			max97236_jack_event(max97236);
			goto max97236_jack_plugged_30;
		}
	}
#else
	msleep(750);
#endif

max97236_jack_plugged_10:
	if (!max97236_jacksw_active(max97236)) {
		max97236_jack_event(max97236);
		goto max97236_jack_plugged_30;
	}
	max97236_begin_detect(max97236);

	count = 10;
	do {
		msleep(20);
		regmap_read(max97236->regmap, M97236_REG_00_STATUS1,
				&status_reg[0]);
	} while (((status_reg[0] & 0x40) != 0x40) && --count);

	status_reg[0] = max97236_get_detect_result(max97236);
	max97236_translate_detected(status_reg, &force_value);
	if(retries<5  && status_reg[1] == 0xCC && status_reg[2] == 0xCC){
                if (status_reg[0] & 0x08) {
        		force_value = 0x02;
        		status_reg[0] = 0x8c;
        		status_reg[1] = 0x30;
        		status_reg[2] = 0x03;
                }else{
        		force_value = 0x12;
        		status_reg[0] = 0x84;
        		status_reg[1] = 0x30;
        		status_reg[2] = 0x03;
                }
	}else if(status_reg[1] == 0xCC && status_reg[2] == 0xCC){
                status_reg[0] = 0x0;
	}
	if (status_reg[0] != 0) {
		regmap_write(max97236->regmap, M97236_REG_20_TEST_ENABLE_2,
			0x00);
	regmap_write(max97236->regmap, M97236_REG_19_STATE_FORCING,
		force_value);
	regmap_update_bits(max97236->regmap,
		M97236_REG_19_STATE_FORCING, 0x20, 0x00);
	regmap_update_bits(max97236->regmap, M97236_REG_1D_ENABLE_1,
		M97236_SHDNN_MASK, M97236_SHDNN_MASK);
	} else {
		max97236_end_detect(max97236);
		if (--retries)
			goto max97236_jack_plugged_10;
	}
max97236_jack_plugged_20:
	max97236_report_jack_state(max97236, status_reg);
	max97236_configure_for_detection(max97236, M97236_AUTO_MODE_0);

	if (max97236->jack_state == SND_JACK_HEADSET)
		max97236_ignore_key_ints(max97236);

	if ((max97236->jack_state == M97236_JACK_STATE_NONE) ||
			(max97236->jack_state == M97236_JACK_STATE_UNKNOWN)) {
		if (verbosity)
			pr_info("%s: M97236_STATE_FLOAT set\n", __func__);
		regmap_write(max97236->regmap,
			M97236_REG_19_STATE_FORCING, M97236_STATE_FLOAT);
	} else {
		if (!max97236_jacksw_active(max97236)) {
			status_reg[0] = 0;
			status_reg[1] = 0;
			goto max97236_jack_plugged_20;
		}
	}
	wake_unlock(&wakelock);

	return;

max97236_jack_plugged_30:
	max97236_configure_for_detection(max97236, M97236_AUTO_MODE_0);
        wake_unlock(&wakelock);
}
Example #2
0
static void max97236_jack_plugged(struct max97236_priv *max97236)
{
	unsigned int status_reg[3] = {0, 0, 0};
	int retries = M97236_DEFAULT_RETRIES;
	int test_number = 1;
	int force_value = 0;
	int count;

	/* Check for spurious interrupt */
	if (!max97236_jacksw_active(max97236))
		goto max97236_jack_plugged_30;

	/* Start debounce while periodically verifying jack presence */
	for (count = 0; count < 24; count++) {
		msleep(20);
		if (!max97236_jacksw_active(max97236))
			goto max97236_jack_plugged_30;
	}

max97236_jack_plugged_10:
	if (!max97236_jacksw_active(max97236))
		goto max97236_jack_plugged_30;

	max97236_begin_detect(max97236, test_number);

	count = 10;
	do {
		msleep(20);
		regmap_read(max97236->regmap, M97236_REG_00_STATUS1,
				&status_reg[0]);
	} while (((status_reg[0] & 0x40) != 0x40) && --count);

	status_reg[0] = max97236_get_detect_result(max97236);
	max97236_translate_detected(status_reg, &force_value);
	max97236_end_detect(max97236);

	if (status_reg[0] != 0) {
		regmap_write(max97236->regmap, M97236_REG_19_STATE_FORCING,
			force_value);
		regmap_update_bits(max97236->regmap,
			M97236_REG_19_STATE_FORCING, 0x20, 0x00);
		regmap_update_bits(max97236->regmap, M97236_REG_1D_ENABLE_1,
			M97236_SHDNN_MASK, M97236_SHDNN_MASK);
	} else {
		if (--retries) {
			goto max97236_jack_plugged_10;
		}
		regmap_write(max97236->regmap, M97236_REG_19_STATE_FORCING,
			force_value);
		regmap_update_bits(max97236->regmap,
			M97236_REG_19_STATE_FORCING, 0x20, 0x00);
	}

max97236_jack_plugged_20:
	max97236_report_jack_state(max97236, status_reg);
	max97236_configure_for_detection(max97236, M97236_AUTO_MODE_0);

	if (max97236->jack_state == SND_JACK_HEADSET)
#ifdef IGNORE_KEY_INT_FUNCTION_ENABLED
		max97236_ignore_key_ints(max97236);
#else
		max97236->ignore_int = 1;
#endif

	if ((max97236->jack_state == M97236_JACK_STATE_NONE) ||
		(max97236->jack_state == M97236_JACK_STATE_UNKNOWN)) {
		regmap_write(max97236->regmap,
			M97236_REG_19_STATE_FORCING, M97236_STATE_FLOAT);
	} else {
	   	if (!max97236_jacksw_active(max97236)) {
			status_reg[0] = 0;
			status_reg[1] = 0;
			goto max97236_jack_plugged_20;
		}
	}

	return;

max97236_jack_plugged_30:
	max97236_configure_for_detection(max97236, M97236_AUTO_MODE_0);
}