/* * Power modes: * active: max scan speed * idle: lower scan speed with automatic transition to active on touch * halt: datasheet says sleep but this is more like halt as the chip * clocks are cut and it can only be brought out of this mode * using the RESET pin.
*/ enum pixcir_power_mode {
PIXCIR_POWER_ACTIVE,
PIXCIR_POWER_IDLE,
PIXCIR_POWER_HALT,
};
for (i = 0; i < touch; i++) {
touchscreen_set_mt_pos(&report->pos[i], &tsdata->prop,
get_unaligned_le16(bufptr),
get_unaligned_le16(bufptr + 2)); if (chip->has_hw_ids) {
report->ids[i] = bufptr[4];
bufptr = bufptr + 5;
} else {
bufptr = bufptr + 4;
}
}
}
staticvoid pixcir_ts_report(struct pixcir_i2c_ts_data *ts, struct pixcir_report_data *report)
{ int slots[PIXCIR_MAX_SLOTS]; int n, i, slot; struct device *dev = &ts->client->dev; conststruct pixcir_i2c_chip_data *chip = ts->chip;
n = report->num_touches; if (n > PIXCIR_MAX_SLOTS)
n = PIXCIR_MAX_SLOTS;
if (!ts->chip->has_hw_ids)
input_mt_assign_slots(ts->input, slots, report->pos, n, 0);
for (i = 0; i < n; i++) { if (chip->has_hw_ids) {
slot = input_mt_get_slot_by_key(ts->input,
report->ids[i]); if (slot < 0) {
dev_dbg(dev, "no free slot for id 0x%x\n",
report->ids[i]); continue;
}
} else {
slot = slots[i];
}
while (tsdata->running) { /* parse packet */
pixcir_ts_parse(tsdata, &report);
/* report it */
pixcir_ts_report(tsdata, &report);
if (gpiod_get_value_cansleep(tsdata->gpio_attb)) { if (report.num_touches) { /* * Last report with no finger up? * Do it now then.
*/
input_mt_sync_frame(tsdata->input);
input_sync(tsdata->input);
} break;
}
if (mode == PIXCIR_POWER_HALT) { if (ts->gpio_wake)
gpiod_set_value_cansleep(ts->gpio_wake, 0);
}
return 0;
}
/* * Set the interrupt mode for the device i.e. ATTB line behaviour * * @polarity : 1 for active high, 0 for active low.
*/ staticint pixcir_set_int_mode(struct pixcir_i2c_ts_data *ts, enum pixcir_int_mode mode, bool polarity)
{ struct device *dev = &ts->client->dev; int ret;
if (device_may_wakeup(&client->dev)) { if (!input_device_enabled(input)) {
ret = pixcir_start(ts); if (ret) {
dev_err(dev, "Failed to start\n"); goto unlock;
}
}
} elseif (input_device_enabled(input)) {
ret = pixcir_stop(ts);
}
if (device_may_wakeup(&client->dev)) { if (!input_device_enabled(input)) {
ret = pixcir_stop(ts); if (ret) {
dev_err(dev, "Failed to stop\n"); goto unlock;
}
}
} elseif (input_device_enabled(input)) {
ret = pixcir_start(ts);
}
tsdata->gpio_attb = devm_gpiod_get(dev, "attb", GPIOD_IN); if (IS_ERR(tsdata->gpio_attb)) return dev_err_probe(dev, PTR_ERR(tsdata->gpio_attb), "Failed to request ATTB gpio\n");
tsdata->gpio_reset = devm_gpiod_get_optional(dev, "reset",
GPIOD_OUT_LOW); if (IS_ERR(tsdata->gpio_reset)) return dev_err_probe(dev, PTR_ERR(tsdata->gpio_reset), "Failed to request RESET gpio\n");
tsdata->gpio_wake = devm_gpiod_get_optional(dev, "wake",
GPIOD_OUT_HIGH); if (IS_ERR(tsdata->gpio_wake)) return dev_err_probe(dev, PTR_ERR(tsdata->gpio_wake), "Failed to get wake gpio\n");
tsdata->gpio_enable = devm_gpiod_get_optional(dev, "enable",
GPIOD_OUT_HIGH); if (IS_ERR(tsdata->gpio_enable)) return dev_err_probe(dev, PTR_ERR(tsdata->gpio_enable), "Failed to get enable gpio\n");
/* Always be in IDLE mode to save power, device supports auto wake */
error = pixcir_set_power_mode(tsdata, PIXCIR_POWER_IDLE); if (error) {
dev_err(dev, "Failed to set IDLE mode\n"); return error;
}
/* Stop device till opened */
error = pixcir_stop(tsdata); if (error) return error;
error = input_register_device(input); if (error) return error;
i2c_set_clientdata(client, tsdata);
return 0;
}
staticconststruct pixcir_i2c_chip_data pixcir_ts_data = {
.max_fingers = 2, /* no hw id support */
};
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.