/* Check for uncalibrated devices */ if (vals[CPM1_CALIBSCALE] == CM32181_CALIBSCALE_DEFAULT) return;
cm32181->calibscale = vals[CPM1_CALIBSCALE]; /* CPM1 lux_per_bit is for the current it value */
cm32181_read_als_it(cm32181, &cm32181->lux_per_bit_base_it);
} #else staticvoid cm32181_acpi_parse_cpm_tables(struct cm32181_chip *cm32181)
{
} #endif/* CONFIG_ACPI */
/** * cm32181_reg_init() - Initialize CM32181 registers * @cm32181: pointer of struct cm32181. * * Initialize CM32181 ambient light sensor register to default values. * * Return: 0 for success; otherwise for error code.
*/ staticint cm32181_reg_init(struct cm32181_chip *cm32181)
{ struct i2c_client *client = cm32181->client; int i;
s32 ret;
ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ID); if (ret < 0) return ret;
/* Initialize registers*/
for_each_set_bit(i, &cm32181->init_regs_bitmap, CM32181_CONF_REG_NUM) {
ret = i2c_smbus_write_word_data(client, i,
cm32181->conf_regs[i]); if (ret < 0) return ret;
}
return 0;
}
/** * cm32181_read_als_it() - Get sensor integration time (ms) * @cm32181: pointer of struct cm32181 * @val2: pointer of int to load the als_it value. * * Report the current integration time in milliseconds. * * Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL.
*/ staticint cm32181_read_als_it(struct cm32181_chip *cm32181, int *val2)
{
u16 als_it; int i;
als_it = cm32181->conf_regs[CM32181_REG_ADDR_CMD];
als_it &= CM32181_CMD_ALS_IT_MASK;
als_it >>= CM32181_CMD_ALS_IT_SHIFT; for (i = 0; i < cm32181->num_als_it; i++) { if (als_it == cm32181->als_it_bits[i]) {
*val2 = cm32181->als_it_values[i]; return IIO_VAL_INT_PLUS_MICRO;
}
}
return -EINVAL;
}
/** * cm32181_write_als_it() - Write sensor integration time * @cm32181: pointer of struct cm32181. * @val: integration time by millisecond. * * Convert integration time (ms) to sensor value. * * Return: i2c_smbus_write_word_data command return value.
*/ staticint cm32181_write_als_it(struct cm32181_chip *cm32181, int val)
{ struct i2c_client *client = cm32181->client;
u16 als_it; int ret, i, n;
n = cm32181->num_als_it; for (i = 0; i < n; i++) if (val <= cm32181->als_it_values[i]) break; if (i >= n)
i = n - 1;
/** * cm32181_get_lux() - report current lux value * @cm32181: pointer of struct cm32181. * * Convert sensor raw data to lux. It depends on integration * time and calibscale variable. * * Return: Positive value is lux, otherwise is error code.
*/ staticint cm32181_get_lux(struct cm32181_chip *cm32181)
{ struct i2c_client *client = cm32181->client; int ret; int als_it;
u64 lux;
ret = cm32181_read_als_it(cm32181, &als_it); if (ret < 0) return -EINVAL;
staticint cm32181_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask)
{ struct cm32181_chip *cm32181 = iio_priv(indio_dev); int ret;
switch (mask) { case IIO_CHAN_INFO_PROCESSED:
ret = cm32181_get_lux(cm32181); if (ret < 0) return ret;
*val = ret; return IIO_VAL_INT; case IIO_CHAN_INFO_CALIBSCALE:
*val = cm32181->calibscale; return IIO_VAL_INT; case IIO_CHAN_INFO_INT_TIME:
*val = 0;
ret = cm32181_read_als_it(cm32181, val2); return ret;
}
return -EINVAL;
}
staticint cm32181_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask)
{ struct cm32181_chip *cm32181 = iio_priv(indio_dev); int ret;
switch (mask) { case IIO_CHAN_INFO_CALIBSCALE:
cm32181->calibscale = val; return val; case IIO_CHAN_INFO_INT_TIME:
ret = cm32181_write_als_it(cm32181, val2); return ret;
}
return -EINVAL;
}
/** * cm32181_get_it_available() - Get available ALS IT value * @dev: pointer of struct device. * @attr: pointer of struct device_attribute. * @buf: pointer of return string buffer. * * Display the available integration time values by millisecond. * * Return: string length.
*/ static ssize_t cm32181_get_it_available(struct device *dev, struct device_attribute *attr, char *buf)
{ struct cm32181_chip *cm32181 = iio_priv(dev_to_iio_dev(dev)); int i, n, len;
n = cm32181->num_als_it; for (i = 0, len = 0; i < n; i++)
len += sprintf(buf + len, "0.%06u ", cm32181->als_it_values[i]); return len + sprintf(buf + len, "\n");
}
indio_dev = devm_iio_device_alloc(dev, sizeof(*cm32181)); if (!indio_dev) return -ENOMEM;
i2c_set_clientdata(client, indio_dev);
/* * Some ACPI systems list 2 I2C resources for the CM3218 sensor, the * SMBus Alert Response Address (ARA, 0x0c) and the actual I2C address. * Detect this and take the following step to deal with it: * 1. When a SMBus Alert capable sensor has an Alert asserted, it will * not respond on its actual I2C address. Read a byte from the ARA * to clear any pending Alerts. * 2. Create a "dummy" client for the actual I2C address and * use that client to communicate with the sensor.
*/ if (ACPI_HANDLE(dev) && client->addr == SMBUS_ALERT_RESPONSE_ADDRESS) { struct i2c_board_info board_info = { .type = "dummy" };
i2c_smbus_read_byte(client);
client = i2c_acpi_new_device(dev, 1, &board_info); if (IS_ERR(client)) return PTR_ERR(client);
ret = devm_add_action_or_reset(dev, cm32181_unregister_dummy_client, client); if (ret) return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.