/* * support _RAW sysfs interface: * * Calculation formula from the datasheet: * pressure = (press_cnt - outputmin) * scale + pmin * with: * * pressure - measured pressure in Pascal * * press_cnt - raw value read from sensor * * pmin - minimum pressure range value of sensor (data->pmin) * * pmax - maximum pressure range value of sensor (data->pmax) * * outputmin - minimum numerical range raw value delivered by sensor * (mpr_func_spec.output_min) * * outputmax - maximum numerical range raw value delivered by sensor * (mpr_func_spec.output_max) * * scale - (pmax - pmin) / (outputmax - outputmin) * * formula of the userspace: * pressure = (raw + offset) * scale * * Values given to the userspace in sysfs interface: * * raw - press_cnt * * offset - (-1 * outputmin) - pmin / scale * note: With all sensors from the datasheet pmin = 0 * which reduces the offset to (-1 * outputmin)
*/
/* * transfer function A: 10% to 90% of 2^24 * transfer function B: 2.5% to 22.5% of 2^24 * transfer function C: 20% to 80% of 2^24
*/ struct mpr_func_spec {
u32 output_min;
u32 output_max;
};
/** * struct mpr_range_config - list of pressure ranges based on nomenclature * @pmin: lowest pressure that can be measured * @pmax: highest pressure that can be measured
*/ struct mpr_range_config { const s32 pmin; const s32 pmax;
};
/** * mpr_read_pressure() - Read pressure value from sensor * @data: Pointer to private data struct. * @press: Output value read from sensor. * * Reading from the sensor by sending and receiving telegrams. * * If there is an end of conversion (EOC) interrupt registered the function * waits for a maximum of one second for the interrupt. * * Context: The function can sleep and data->lock should be held when calling it * Return: * * 0 - OK, the pressure value could be read * * -ETIMEDOUT - Timeout while waiting for the EOC interrupt or busy flag is * still set after nloops attempts of reading
*/ staticint mpr_read_pressure(struct mpr_data *data, s32 *press)
{ struct device *dev = data->dev; int ret, i; int nloops = 10;
reinit_completion(&data->completion);
ret = data->ops->write(data, MPR_CMD_SYNC, MPR_PKT_SYNC_LEN); if (ret < 0) {
dev_err(dev, "error while writing ret: %d\n", ret); return ret;
}
if (data->irq > 0) {
ret = wait_for_completion_timeout(&data->completion, HZ); if (!ret) {
dev_err(dev, "timeout while waiting for eoc irq\n"); return -ETIMEDOUT;
}
} else { /* wait until status indicates data is ready */ for (i = 0; i < nloops; i++) { /* * datasheet only says to wait at least 5 ms for the * data but leave the maximum response time open * --> let's try it nloops (10) times which seems to be * quite long
*/
usleep_range(5000, 10000);
ret = data->ops->read(data, MPR_CMD_NOP, 1); if (ret < 0) {
dev_err(dev, "error while reading, status: %d\n",
ret); return ret;
} if (!(data->buffer[0] & MPR_ST_ERR_FLAG)) break;
} if (i == nloops) {
dev_err(dev, "timeout while reading\n"); return -ETIMEDOUT;
}
}
ret = data->ops->read(data, MPR_CMD_NOP, MPR_PKT_NOP_LEN); if (ret < 0) return ret;
if (data->buffer[0] & MPR_ST_ERR_FLAG) {
dev_err(data->dev, "unexpected status byte %02x\n", data->buffer[0]); return -ETIMEDOUT;
}
ret = devm_regulator_get_enable(dev, "vdd"); if (ret) return dev_err_probe(dev, ret, "can't get and enable vdd supply\n");
ret = data->ops->init(data->dev); if (ret) return ret;
ret = device_property_read_u32(dev, "honeywell,transfer-function", &func); if (ret) return dev_err_probe(dev, ret, "honeywell,transfer-function could not be read\n");
data->function = func - 1; if (data->function > MPR_FUNCTION_C) return dev_err_probe(dev, -EINVAL, "honeywell,transfer-function %d invalid\n",
data->function);
ret = device_property_read_string(dev, "honeywell,pressure-triplet",
&triplet); if (ret) {
ret = device_property_read_u32(dev, "honeywell,pmin-pascal",
&data->pmin); if (ret) return dev_err_probe(dev, ret, "honeywell,pmin-pascal could not be read\n");
ret = device_property_read_u32(dev, "honeywell,pmax-pascal",
&data->pmax); if (ret) return dev_err_probe(dev, ret, "honeywell,pmax-pascal could not be read\n");
} else {
ret = device_property_match_property_string(dev, "honeywell,pressure-triplet",
mpr_triplet_variants,
MPR_VARIANTS_MAX); if (ret < 0) return dev_err_probe(dev, -EINVAL, "honeywell,pressure-triplet is invalid\n");
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.