예제 #1
0
static void max97236_jack_event(struct max97236_priv *max97236)
{
	unsigned int status_reg[3];

	regmap_read(max97236->regmap, M97236_REG_00_STATUS1, &status_reg[0]);
	regmap_read(max97236->regmap, M97236_REG_01_STATUS2, &status_reg[1]);

	/* Key press or jack removal? */
	if ((status_reg[0] & M97236_IMBH_MASK)      ||
			(status_reg[0] & M97236_IMCSW_MASK) ||
			(status_reg[1] & M97236_IKEY_MASK)) {
		max97236_keypress(max97236, status_reg);
	} else {
		if (max97236_jacksw_active(max97236))
			goto max97236_jack_event_10;
		regmap_update_bits(max97236->regmap, M97236_REG_07_LEFT_VOLUME,
				M97236_MUTEL_MASK, M97236_MUTEL_MASK);
		regmap_update_bits(max97236->regmap, M97236_REG_08_RIGHT_VOLUME,
				M97236_MUTER_MASK, M97236_MUTER_MASK);
		regmap_write(max97236->regmap, M97236_REG_19_STATE_FORCING,
				M97236_STATE_FLOAT);
		regmap_update_bits(max97236->regmap, M97236_REG_1D_ENABLE_1,
				M97236_SHDNN_MASK, 0);
		status_reg[0] = 0;
		status_reg[1] = 0;
		status_reg[2] = 0;
		max97236_report_jack_state(max97236, status_reg);
	}

max97236_jack_event_10:
	max97236_configure_for_detection(max97236, M97236_AUTO_MODE_0);

	return;
}
예제 #2
0
static void max97236_jack_event(struct max97236_priv *max97236)
{
	unsigned int status_reg[3];
	int count;

	regmap_read(max97236->regmap, M97236_REG_00_STATUS1,
			&status_reg[0]);
	regmap_read(max97236->regmap, M97236_REG_01_STATUS2,
			&status_reg[1]);

	/* First check for a key press */
	if (((status_reg[0] & M97236_IMBH_MASK)     ||
			(status_reg[0] & M97236_IMCSW_MASK) ||
			(status_reg[1] & M97236_IKEY_MASK)) &&
			(status_reg[0] & 0x80)) {
		max97236_keypress(max97236, status_reg);
	} else {
		if (max97236_jacksw_active(max97236))
			goto max97236_jack_event_10;

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

		regmap_read(max97236->regmap, M97236_REG_00_STATUS1,
				&status_reg[0]);
		regmap_read(max97236->regmap, M97236_REG_01_STATUS2,
				&status_reg[1]);
		regmap_read(max97236->regmap, M97236_REG_02_STATUS3,
				&status_reg[2]);

		/* test for jack switch malfunction indication */
		if ((status_reg[1] & M97236_IJACKSWINC_MASK) &&
				(status_reg[0] & 0x80))
			pr_err("JACKSWINC set\n");

		max97236_report_jack_state(max97236, status_reg);
		if (max97236->jack_state == M97236_JACK_STATE_NONE) {
			regmap_update_bits(max97236->regmap,
					M97236_REG_07_LEFT_VOLUME,
					M97236_MUTEL_MASK, M97236_MUTEL_MASK);
			regmap_update_bits(max97236->regmap,
					M97236_REG_08_RIGHT_VOLUME,
					M97236_MUTER_MASK, M97236_MUTER_MASK);
			regmap_update_bits(max97236->regmap,
					M97236_REG_1D_ENABLE_1,
					M97236_SHDNN_MASK, 0);
		}
	}

max97236_jack_event_10:
	max97236_configure_for_detection(max97236, M97236_AUTO_MODE_1);

	return;
}
예제 #3
0
static void max97236_jack_plugged(struct max97236_priv *max97236)
{
	unsigned int status_reg[3];
	int count;

	if (!max97236_jacksw_active(max97236))
		goto max97236_jack_plugged_20;

	msleep(250);

	regmap_update_bits(max97236->regmap, M97236_REG_1D_ENABLE_1,
			M97236_SHDNN_MASK,
			M97236_SHDNN_MASK);

max97236_jack_plugged_10:
	max97236_reset(max97236);
	count = M97236_DEFAULT_JACK_DETECT_DELAY;
	do {
		msleep(20);
		regmap_read(max97236->regmap, M97236_REG_00_STATUS1,
				&status_reg[0]);
	} while (((status_reg[0] & M97236_DDONE_MASK) != M97236_DDONE_MASK) &&
			--count);

	regmap_read(max97236->regmap, M97236_REG_00_STATUS1, &status_reg[0]);
	regmap_read(max97236->regmap, M97236_REG_01_STATUS2, &status_reg[1]);
	regmap_read(max97236->regmap, M97236_REG_02_STATUS3, &status_reg[2]);

	pr_info("%s: status 0x%02X, 0x%02X, count %d\n", __func__, status_reg[0], status_reg[1], count);

	max97236_report_jack_state(max97236, status_reg);

	if (!max97236_jacksw_active(max97236)) {
		goto max97236_jack_plugged_10;
	}

	if (max97236->jack_state == SND_JACK_HEADSET)
		max97236->ignore_int = 1;

max97236_jack_plugged_20:
	max97236_configure_for_detection(max97236, M97236_AUTO_MODE_1);
}
예제 #4
0
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);
}
예제 #5
0
static void max97236_jack_event(struct max97236_priv *max97236)
{
	unsigned int status_reg[3];
	int i;
	int test_value = 0;
 
	wake_lock(&wakelock_h);

	regmap_read(max97236->regmap, M97236_REG_00_STATUS1, &status_reg[0]);
	regmap_read(max97236->regmap, M97236_REG_01_STATUS2, &status_reg[1]);

	/* Overwrite above code using board id */
	if (board_info.board_id == BOARD_E1690) {
		test_value = 0;
	} else { /* ERS */
		test_value = 4;
	}

	/* Key press or jack removal? */
	/* For Key press, it need make sure it is headset connected */
	for (i = 0; i < 4; i++) {
		if ((status_reg[0] & M97236_JACKSW_MASK) == test_value) {
			break;
		} else {
			msleep(20);
			regmap_read(max97236->regmap,
					M97236_REG_00_STATUS1, &status_reg[0]);
			regmap_read(max97236->regmap,
					M97236_REG_01_STATUS2, &status_reg[1]);
		}
	}
	if (((status_reg[0] & M97236_IMBH_MASK)      ||
			(status_reg[0] & M97236_IMCSW_MASK) ||
			(status_reg[1] & M97236_IKEY_MASK)) &&
			(status_reg[0] & M97236_JACKSW_MASK) == test_value)
	{
/* headset detect feature   WJ  21/01/14 */
		if (max97236_jacksw_active(max97236)){
		    max97236_keypress(max97236, status_reg);
                }else{
        		regmap_update_bits(max97236->regmap, M97236_REG_07_LEFT_VOLUME,
        				M97236_MUTEL_MASK, M97236_MUTEL_MASK);
        		regmap_update_bits(max97236->regmap, M97236_REG_08_RIGHT_VOLUME,
        				M97236_MUTER_MASK, M97236_MUTER_MASK);
        		regmap_write(max97236->regmap, M97236_REG_23_TEST_DATA_3, 0x00);
        		regmap_write(max97236->regmap, M97236_REG_19_STATE_FORCING,
        				M97236_STATE_FLOAT);
        		regmap_update_bits(max97236->regmap, M97236_REG_1D_ENABLE_1,
        				M97236_SHDNN_MASK, 0);
        		status_reg[0] = 0;
        		status_reg[1] = 0;
        		status_reg[2] = 0;
        		max97236_report_jack_state(max97236, status_reg);
                }
/* headset detect feature   WJ  21/01/14  end*/
	} else {
		if (max97236_jacksw_active(max97236))
			goto max97236_jack_event_10;
		regmap_update_bits(max97236->regmap, M97236_REG_07_LEFT_VOLUME,
				M97236_MUTEL_MASK, M97236_MUTEL_MASK);
		regmap_update_bits(max97236->regmap, M97236_REG_08_RIGHT_VOLUME,
				M97236_MUTER_MASK, M97236_MUTER_MASK);
		regmap_write(max97236->regmap, M97236_REG_23_TEST_DATA_3, 0x00);
		regmap_write(max97236->regmap, M97236_REG_19_STATE_FORCING,
				M97236_STATE_FLOAT);
		if (verbosity)
			pr_info("%s: M97236_STATE_FLOAT set\n", __func__);
		regmap_update_bits(max97236->regmap, M97236_REG_1D_ENABLE_1,
				M97236_SHDNN_MASK, 0);
		status_reg[0] = 0;
		status_reg[1] = 0;
		status_reg[2] = 0;
		max97236_report_jack_state(max97236, status_reg);
	}

max97236_jack_event_10:
	max97236_configure_for_detection(max97236, M97236_AUTO_MODE_0);
	wake_unlock(&wakelock_h);
	return;
}
예제 #6
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);
}