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;
}