static int si1145_initialize()

in light/si1145.c [1012:1139]


static int si1145_initialize(struct si1145_data *data)
{
	struct i2c_client *client = data->client;
	int ret;

	ret = i2c_smbus_write_byte_data(client, SI1145_REG_COMMAND,
					SI1145_CMD_RESET);
	if (ret < 0)
		return ret;
	msleep(SI1145_COMMAND_TIMEOUT_MS);

	/* Hardware key, magic value */
	ret = i2c_smbus_write_byte_data(client, SI1145_REG_HW_KEY, 0x17);
	if (ret < 0)
		return ret;
	msleep(SI1145_COMMAND_TIMEOUT_MS);

	/* Turn off autonomous mode */
	ret = si1145_set_meas_rate(data, 0);
	if (ret < 0)
		return ret;

	/* Initialize sampling freq to 10 Hz */
	ret = si1145_store_samp_freq(data, 10);
	if (ret < 0)
		return ret;

	/* Set LED currents to 45 mA; have 4 bits, see Table 2 in datasheet */
	switch (data->part_info->num_leds) {
	case 3:
		ret = i2c_smbus_write_byte_data(client,
						SI1145_REG_PS_LED3,
						SI1145_LED_CURRENT_45mA);
		if (ret < 0)
			return ret;
		fallthrough;
	case 2:
		ret = i2c_smbus_write_byte_data(client,
						SI1145_REG_PS_LED21,
						(SI1145_LED_CURRENT_45mA << 4) |
						SI1145_LED_CURRENT_45mA);
		break;
	case 1:
		ret = i2c_smbus_write_byte_data(client,
						SI1145_REG_PS_LED21,
						SI1145_LED_CURRENT_45mA);
		break;
	default:
		ret = 0;
		break;
	}
	if (ret < 0)
		return ret;

	/* Set normal proximity measurement mode */
	ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_MISC,
			       SI1145_PS_ADC_MODE_NORMAL);
	if (ret < 0)
		return ret;

	ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_GAIN, 0x01);
	if (ret < 0)
		return ret;

	/* ADC_COUNTER should be one complement of ADC_GAIN */
	ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_COUNTER, 0x06 << 4);
	if (ret < 0)
		return ret;

	/* Set ALS visible measurement mode */
	ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_MISC,
			       SI1145_ADC_MISC_RANGE);
	if (ret < 0)
		return ret;

	ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_GAIN, 0x03);
	if (ret < 0)
		return ret;

	ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_COUNTER,
			       0x04 << 4);
	if (ret < 0)
		return ret;

	/* Set ALS IR measurement mode */
	ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_MISC,
			       SI1145_ADC_MISC_RANGE);
	if (ret < 0)
		return ret;

	ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_GAIN, 0x01);
	if (ret < 0)
		return ret;

	ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_COUNTER,
			       0x06 << 4);
	if (ret < 0)
		return ret;

	/*
	 * Initialize UCOEF to default values in datasheet
	 * These registers are normally zero on reset
	 */
	if (data->part_info == &si1145_part_info[SI1132] ||
		data->part_info == &si1145_part_info[SI1145] ||
		data->part_info == &si1145_part_info[SI1146] ||
		data->part_info == &si1145_part_info[SI1147]) {
		ret = i2c_smbus_write_byte_data(data->client,
						SI1145_REG_UCOEF1,
						SI1145_UCOEF1_DEFAULT);
		if (ret < 0)
			return ret;
		ret = i2c_smbus_write_byte_data(data->client,
				SI1145_REG_UCOEF2, SI1145_UCOEF2_DEFAULT);
		if (ret < 0)
			return ret;
		ret = i2c_smbus_write_byte_data(data->client,
				SI1145_REG_UCOEF3, SI1145_UCOEF3_DEFAULT);
		if (ret < 0)
			return ret;
		ret = i2c_smbus_write_byte_data(data->client,
				SI1145_REG_UCOEF4, SI1145_UCOEF4_DEFAULT);
		if (ret < 0)
			return ret;
	}

	return 0;
}