static unsigned int check_firmware_rev(struct ssp_data *data)
{
	char chTxData = MSG2SSP_AP_FIRMWARE_REV;
	char chRxBuf[3] = {0,};
	unsigned int uRev = SSP_INVALID_REVISION;
	int iRet;

	iRet = ssp_i2c_read(data, &chTxData, 1, chRxBuf, 3, 0);
	if (iRet != SUCCESS) {
		pr_err("[SSP]: %s - i2c fail %d\n", __func__, iRet);
	} else
		uRev = ((unsigned int)chRxBuf[0] << 16)
			| ((unsigned int)chRxBuf[1] << 8) | chRxBuf[2];
	return uRev;
}
Пример #2
0
static int ssp_receive_large_msg(struct ssp_sensorhub_data *hub_data,
				u8 sub_cmd)
{
	char send_data[2] = { 0, };
	char receive_data[2] = { 0, };
	char *large_msg_data; /* Nth large msg data */
	int length = 0; /* length of Nth large msg */
	int data_locater = 0; /* large_library_data current position */
	int total_msg_number; /* total number of large msg */
	int msg_number; /* current number of large msg */
	int ret = 0;

	/* receive the first msg length */
	send_data[0] = MSG2SSP_STT;
	send_data[1] = sub_cmd;

	/* receive_data(msg length) is two byte because msg is large */
	ret = ssp_i2c_read(hub_data->ssp_data, send_data, 2,
			receive_data, 2, 0);
	if (ret < 0) {
		pr_err("%s: MSG2SSP_STT i2c err(%d)", __func__, ret);
		return ret;
	}

	/* get the first msg length */
	length = ((unsigned int)receive_data[0] << 8)
		+ (unsigned int)receive_data[1];
	if (length < 3) {
		/* do not print err message with power-up */
		if (sub_cmd != SUBCMD_POWEREUP)
			pr_err("%s: 1st large msg data not ready(length=%d)",
				__func__, length);
		return -EINVAL;
	}

	/* receive the first msg data */
	send_data[0] = MSG2SSP_SRM;
	large_msg_data = kzalloc((length  * sizeof(char)), GFP_KERNEL);
	ret = ssp_i2c_read(hub_data->ssp_data, send_data, 1,
			large_msg_data, length, 0);
	if (ret < 0) {
		pr_err("%s: receive 1st large msg err(%d)", __func__, ret);
		kfree(large_msg_data);
		return ret;
	}

	/* empty the previous large library data */
	if (hub_data->large_library_length != 0)
		kfree(hub_data->large_library_data);

	/* large_msg_data[0] of the first msg: total number of large msg
	 * large_msg_data[1-2] of the first msg: total msg length
	 * large_msg_data[3-N] of the first msg: the first msg data itself */
	total_msg_number = large_msg_data[0];
	hub_data->large_library_length
			= (int)((unsigned int)large_msg_data[1] << 8)
				+ (unsigned int)large_msg_data[2];
	hub_data->large_library_data
		= kzalloc((hub_data->large_library_length * sizeof(char)),
			GFP_KERNEL);

	/* copy the fist msg data into large_library_data */
	memcpy(hub_data->large_library_data, &large_msg_data[3],
		(length - 3) * sizeof(char));
	kfree(large_msg_data);

	data_locater = length - 3;

	/* 2nd, 3rd,...Nth msg */
	for (msg_number = 0; msg_number < total_msg_number; msg_number++) {
		/* receive Nth msg length */
		send_data[0] = MSG2SSP_STT;
		send_data[1] = 0x81 + msg_number;

		/* receive_data(msg length) is two byte because msg is large */
		ret = ssp_i2c_read(hub_data->ssp_data, send_data, 2,
				receive_data, 2, 0);
		if (ret < 0) {
			pr_err("%s: MSG2SSP_STT i2c err(%d)",
					__func__, ret);
			return ret;
		}

		/* get the Nth msg length */
		length = ((unsigned int)receive_data[0] << 8)
			+ (unsigned int)receive_data[1];
		if (length <= 0) {
			pr_err("%s: %dth large msg data not ready(length=%d)",
					__func__, msg_number + 2, length);
			return -EINVAL;
		}

		large_msg_data = kzalloc((length  * sizeof(char)),
					GFP_KERNEL);

		/* receive Nth msg data */
		send_data[0] = MSG2SSP_SRM;
		ret = ssp_i2c_read(hub_data->ssp_data, send_data, 1,
				large_msg_data, length, 0);
		if (ret < 0) {
			pr_err("%s: recieve %dth large msg err(%d)",
			       __func__, msg_number + 2, ret);
			kfree(large_msg_data);
			return ret;
		}

		/* copy(append) Nth msg data into large_library_data */
		memcpy(&hub_data->large_library_data[data_locater],
			large_msg_data,	length * sizeof(char));
		data_locater += length;
		kfree(large_msg_data);
	}

	return hub_data->large_library_length;
}