/** * struct aht10_data - All the data required to operate an AHT10/AHT20 chip * @client: the i2c client associated with the AHT10/AHT20 * @lock: a mutex that is used to prevent parallel access to the * i2c client * @min_poll_interval: the minimum poll interval * While the poll rate limit is not 100% necessary, * the datasheet recommends that a measurement * is not performed too often to prevent * the chip from warming up due to the heat it generates. * If it's unwanted, it can be ignored setting it to * it to 0. Default value is 2000 ms * @previous_poll_time: the previous time that the AHT10/AHT20 * was polled * @temperature: the latest temperature value received from * the AHT10/AHT20 * @humidity: the latest humidity value received from the * AHT10/AHT20 * @crc8: crc8 support flag * @meas_size: measurements data size
*/
struct aht10_data { struct i2c_client *client; /* * Prevent simultaneous access to the i2c * client and previous_poll_time
*/ struct mutex lock;
ktime_t min_poll_interval;
ktime_t previous_poll_time; int temperature; int humidity; bool crc8; unsignedint meas_size;
};
/* * aht10_init() - Initialize an AHT10/AHT20 chip * @data: the data associated with this AHT10/AHT20 chip * Return: 0 if successful, 1 if not
*/ staticint aht10_init(struct aht10_data *data)
{ const u8 cmd_init[] = {AHT10_CMD_INIT, AHT10_CAL_ENABLED | AHT10_MODE_CYC,
0x00}; int res;
u8 status; struct i2c_client *client = data->client;
res = i2c_master_send(client, cmd_init, 3); if (res < 0) return res;
res = i2c_master_recv(client, &status, 1); if (res != 1) return -ENODATA;
if (status & AHT10_BUSY) return -EBUSY;
return 0;
}
/* * aht10_polltime_expired() - check if the minimum poll interval has * expired * @data: the data containing the time to compare * Return: 1 if the minimum poll interval has expired, 0 if not
*/ staticint aht10_polltime_expired(struct aht10_data *data)
{
ktime_t current_time = ktime_get_boottime();
ktime_t difference = ktime_sub(current_time, data->previous_poll_time);
/* * crc8_check() - check crc of the sensor's measurements * @raw_data: data frame received from sensor(including crc as the last byte) * @count: size of the data frame * Return: 0 if successful, 1 if not
*/ staticint crc8_check(u8 *raw_data, int count)
{ /* * crc calculated on the whole frame(including crc byte) should yield * zero in case of correctly received bytes
*/ return crc8(crc8_table, raw_data, count, CRC8_INIT_VALUE);
}
/* * aht10_read_values() - read and parse the raw data from the AHT10/AHT20 * @data: the struct aht10_data to use for the lock * Return: 0 if successful, 1 if not
*/ staticint aht10_read_values(struct aht10_data *data)
{ const u8 cmd_meas[] = {AHT10_CMD_MEAS, 0x33, 0x00};
u32 temp, hum; int res;
u8 raw_data[AHT20_MEAS_SIZE]; struct i2c_client *client = data->client;
mutex_lock(&data->lock); if (!aht10_polltime_expired(data)) {
mutex_unlock(&data->lock); return 0;
}
res = i2c_master_send(client, cmd_meas, sizeof(cmd_meas)); if (res < 0) {
mutex_unlock(&data->lock); return res;
}
/* * aht10_interval_write() - store the given minimum poll interval. * Return: 0 on success, -EINVAL if a value lower than the * AHT10_MIN_POLL_INTERVAL is given
*/ static ssize_t aht10_interval_write(struct aht10_data *data, long val)
{
data->min_poll_interval = ms_to_ktime(clamp_val(val, 2000, LONG_MAX)); return 0;
}
/* * aht10_interval_read() - read the minimum poll interval * in milliseconds
*/ static ssize_t aht10_interval_read(struct aht10_data *data, long *val)
{
*val = ktime_to_ms(data->min_poll_interval); return 0;
}
/* * aht10_temperature1_read() - read the temperature in millidegrees
*/ staticint aht10_temperature1_read(struct aht10_data *data, long *val)
{ int res;
res = aht10_read_values(data); if (res < 0) return res;
*val = data->temperature; return 0;
}
/* * aht10_humidity1_read() - read the relative humidity in millipercent
*/ staticint aht10_humidity1_read(struct aht10_data *data, long *val)
{ int res;
res = aht10_read_values(data); if (res < 0) return res;
*val = data->humidity; return 0;
}
static umode_t aht10_hwmon_visible(constvoid *data, enum hwmon_sensor_types type,
u32 attr, int channel)
{ switch (type) { case hwmon_temp: case hwmon_humidity: return 0444; case hwmon_chip: return 0644; default: return 0;
}
}
staticint aht10_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *val)
{ struct aht10_data *data = dev_get_drvdata(dev);
switch (type) { case hwmon_temp: return aht10_temperature1_read(data, val); case hwmon_humidity: return aht10_humidity1_read(data, val); case hwmon_chip: return aht10_interval_read(data, val); default: return -EOPNOTSUPP;
}
}
staticint aht10_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long val)
{ struct aht10_data *data = dev_get_drvdata(dev);
MODULE_AUTHOR("Johannes Cornelis Draaijer ");
MODULE_DESCRIPTION("AHT10/AHT20 Temperature and Humidity sensor driver");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL v2");
Messung V0.5
¤ 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.0.10Bemerkung:
(vorverarbeitet)
¤
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.