/* * Interrupt modes: * periodical: interrupt is asserted periodically * compare coordinates: interrupt is asserted when coordinates change * indicate touch: interrupt is asserted during touch
*/ #define AUO_PIXCIR_INT_PERIODICAL 0x00 #define AUO_PIXCIR_INT_COMP_COORD 0x01 #define AUO_PIXCIR_INT_TOUCH_IND 0x02 #define AUO_PIXCIR_INT_MODE_MASK 0x03
/* * Power modes: * active: scan speed 60Hz * sleep: scan speed 10Hz can be auto-activated, wakeup on 1st touch * deep sleep: scan speed 1Hz can only be entered or left manually.
*/ #define AUO_PIXCIR_POWER_ACTIVE 0x00 #define AUO_PIXCIR_POWER_SLEEP 0x01 #define AUO_PIXCIR_POWER_DEEP_SLEEP 0x02 #define AUO_PIXCIR_POWER_MASK 0x03
/* determine touch major, minor and orientation */
point[i].area_major = max(raw_area[2 * i], raw_area[2 * i + 1]);
point[i].area_minor = min(raw_area[2 * i], raw_area[2 * i + 1]);
point[i].orientation = raw_area[2 * i] > raw_area[2 * i + 1];
}
return 0;
}
static irqreturn_t auo_pixcir_interrupt(int irq, void *dev_id)
{ struct auo_pixcir_ts *ts = dev_id; struct auo_point_t point[AUO_PIXCIR_REPORT_POINTS]; int i; int ret; int fingers = 0; int abs = -1;
while (!ts->stopped) {
/* check for up event in touch touch_ind_mode */ if (ts->touch_ind_mode) { if (gpiod_get_value_cansleep(ts->gpio_int) == 0) {
input_mt_sync(ts->input);
input_report_key(ts->input, BTN_TOUCH, 0);
input_sync(ts->input); break;
}
}
ret = auo_pixcir_collect_data(ts, point); if (ret < 0) { /* we want to loop only in touch_ind_mode */ if (!ts->touch_ind_mode) break;
/* * Set the power mode of the device. * Valid modes are * - AUO_PIXCIR_POWER_ACTIVE * - AUO_PIXCIR_POWER_SLEEP - automatically left on first touch * - AUO_PIXCIR_POWER_DEEP_SLEEP
*/ staticint auo_pixcir_power_mode(struct auo_pixcir_ts *ts, int mode)
{ struct i2c_client *client = ts->client; int ret;
ret = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_POWER_MODE); if (ret < 0) {
dev_err(&client->dev, "unable to read reg %Xh, %d\n",
AUO_PIXCIR_REG_POWER_MODE, ret); return ret;
}
ret &= ~AUO_PIXCIR_POWER_MASK;
ret |= mode;
ret = i2c_smbus_write_byte_data(client, AUO_PIXCIR_REG_POWER_MODE, ret); if (ret) {
dev_err(&client->dev, "unable to write reg %Xh, %d\n",
AUO_PIXCIR_REG_POWER_MODE, ret); return ret;
}
return 0;
}
staticint auo_pixcir_int_config(struct auo_pixcir_ts *ts, int int_setting)
{ struct i2c_client *client = ts->client; int ret;
ret = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_INT_SETTING); if (ret < 0) {
dev_err(&client->dev, "unable to read reg %Xh, %d\n",
AUO_PIXCIR_REG_INT_SETTING, ret); return ret;
}
ret &= ~AUO_PIXCIR_INT_MODE_MASK;
ret |= int_setting;
ret |= AUO_PIXCIR_INT_POL_HIGH; /* always use high for interrupts */
ret = i2c_smbus_write_byte_data(client, AUO_PIXCIR_REG_INT_SETTING,
ret); if (ret < 0) {
dev_err(&client->dev, "unable to write reg %Xh, %d\n",
AUO_PIXCIR_REG_INT_SETTING, ret); return ret;
}
/* control the generation of interrupts on the device side */ staticint auo_pixcir_int_toggle(struct auo_pixcir_ts *ts, bool enable)
{ struct i2c_client *client = ts->client; int ret;
ret = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_INT_SETTING); if (ret < 0) {
dev_err(&client->dev, "unable to read reg %Xh, %d\n",
AUO_PIXCIR_REG_INT_SETTING, ret); return ret;
}
if (enable)
ret |= AUO_PIXCIR_INT_ENABLE; else
ret &= ~AUO_PIXCIR_INT_ENABLE;
ret = i2c_smbus_write_byte_data(client, AUO_PIXCIR_REG_INT_SETTING,
ret); if (ret < 0) {
dev_err(&client->dev, "unable to write reg %Xh, %d\n",
AUO_PIXCIR_REG_INT_SETTING, ret); return ret;
}
/* when configured as wakeup source, device should always wake system * therefore start device if necessary
*/ if (device_may_wakeup(&client->dev)) { /* need to start device if not open, to be wakeup source */ if (!input_device_enabled(input)) {
ret = auo_pixcir_start(ts); if (ret) goto unlock;
}
enable_irq_wake(client->irq);
ret = auo_pixcir_power_mode(ts, AUO_PIXCIR_POWER_SLEEP);
} elseif (input_device_enabled(input)) {
ret = auo_pixcir_stop(ts);
}
error = devm_add_action_or_reset(&client->dev, auo_pixcir_reset, ts); if (error) {
dev_err(&client->dev, "failed to register reset action, %d\n",
error); return error;
}
msleep(200);
version = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_VERSION); if (version < 0) {
error = version; return error;
}
dev_info(&client->dev, "firmware version 0x%X\n", version);
/* default to asserting the interrupt when the screen is touched */
error = auo_pixcir_int_config(ts, AUO_PIXCIR_INT_TOUCH_IND); if (error) return error;
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.