struct continuous {
u16 id; /* codec id */
u8 code; /* continuous code */
u8 reads; /* number of coord reads per read cycle */
u32 speed; /* number of coords per second */
};
if (cpu_is_pxa27x()) { while (pxa2xx_ac97_read_misr() & (1 << 2))
pxa2xx_ac97_read_modr();
} elseif (cpu_is_pxa3xx()) { for (count = 0; count < 16; count++)
pxa2xx_ac97_read_modr();
}
}
staticint wm97xx_acc_pen_down(struct wm97xx *wm)
{
u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES; int reads = 0; static u16 last, tries;
/* When the AC97 queue has been drained we need to allow time *tobufferupsamplesotherwiseweendupspinningpolling *forsamples.Thecontrollercan'thaveasuitablylow *thresholdsettousethenotificationsitgives.
*/
msleep(1);
if (tries > 5) {
tries = 0; return RC_PENUP;
}
x = pxa2xx_ac97_read_modr(); if (x == last) {
tries++; return RC_AGAIN;
}
last = x; do { if (reads)
x = pxa2xx_ac97_read_modr();
y = pxa2xx_ac97_read_modr(); if (pressure)
p = pxa2xx_ac97_read_modr();
dev_dbg(wm->dev, "Raw coordinates: x=%x, y=%x, p=%x\n",
x, y, p);
/* coordinate is good */
tries = 0;
input_report_abs(wm->input_dev, ABS_X, x & 0xfff);
input_report_abs(wm->input_dev, ABS_Y, y & 0xfff);
input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff);
input_report_key(wm->input_dev, BTN_TOUCH, (p != 0));
input_sync(wm->input_dev);
reads++;
} while (reads < cinfo[sp_idx].reads);
up: return RC_PENDOWN | RC_AGAIN;
}
staticint wm97xx_acc_startup(struct wm97xx *wm)
{ int idx = 0, ret = 0;
/* check we have a codec */ if (wm->ac97 == NULL) return -ENODEV;
/* Go you big red fire engine */ for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) { if (wm->id != cinfo[idx].id) continue;
sp_idx = idx; if (cont_rate <= cinfo[idx].speed) break;
}
wm->acc_rate = cinfo[sp_idx].code;
wm->acc_slot = ac97_touch_slot;
dev_info(wm->dev, "mainstone accelerated touchscreen driver, %d samples/sec\n",
cinfo[sp_idx].speed);
if (pen_int) {
gpiod_irq = gpiod_get(wm->dev, "touch", GPIOD_IN); if (IS_ERR(gpiod_irq))
pen_int = 0;
}
if (pen_int) {
wm->pen_irq = gpiod_to_irq(gpiod_irq);
irq_set_irq_type(wm->pen_irq, IRQ_TYPE_EDGE_BOTH);
}
/* codec specific irq config */ if (pen_int) { switch (wm->id) { case WM9705_ID2: break; case WM9712_ID2: case WM9713_ID2: /* use PEN_DOWN GPIO 13 to assert IRQ on GPIO line 2 */
wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
WM97XX_GPIO_POL_HIGH,
WM97XX_GPIO_STICKY,
WM97XX_GPIO_WAKE);
wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT,
WM97XX_GPIO_POL_HIGH,
WM97XX_GPIO_NOTSTICKY,
WM97XX_GPIO_NOWAKE); break; default:
dev_err(wm->dev, "pen down irq not supported on this device\n");
pen_int = 0; break;
}
}
return ret;
}
staticvoid wm97xx_acc_shutdown(struct wm97xx *wm)
{ /* codec specific deconfig */ if (pen_int) { if (gpiod_irq)
gpiod_put(gpiod_irq);
wm->pen_irq = 0;
}
}
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.