/* * Touchscreen absolute values * * These parameters are used to help the input layer discard out of * range readings and reduce jitter etc. * * o min, max:- indicate the min and max values your touch screen returns * o fuzz:- use a higher number to reduce jitter * * The default values correspond to Mainstone II in QVGA mode * * Please read * Documentation/input/input-programming.rst for more details.
*/
if (wm->ac97)
wm->ac97->bus->ops->write(wm->ac97, reg, val);
}
EXPORT_SYMBOL_GPL(wm97xx_reg_write);
/** * wm97xx_read_aux_adc - Read the aux adc. * @wm: wm97xx device. * @adcsel: codec ADC to be read * * Reads the selected AUX ADC.
*/
int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel)
{ int power_adc = 0, auxval;
u16 power = 0; int rc = 0; int timeout = 0;
/* get codec */
mutex_lock(&wm->codec_mutex);
/* When the touchscreen is not in use, we may have to power up * the AUX ADC before we can use sample the AUX inputs->
*/ if (wm->id == WM9713_ID2 &&
(power = wm97xx_reg_read(wm, AC97_EXTENDED_MID)) & 0x8000) {
power_adc = 1;
wm97xx_reg_write(wm, AC97_EXTENDED_MID, power & 0x7fff);
}
/* Prepare the codec for AUX reading */
wm->codec->aux_prepare(wm);
/* Turn polling mode on to read AUX ADC */
wm->pen_probably_down = 1;
/** * wm97xx_set_gpio - Set the status of a codec GPIO. * @wm: wm97xx device. * @gpio: gpio * @status: status * * Set the status of a codec GPIO pin
*/
/* * Configure the WM97XX_PRP value to use while system is suspended. * If a value other than 0 is set then WM97xx pen detection will be * left enabled in the configured mode while the system is in suspend, * the device has users and suspend has not been disabled via the * wakeup sysfs entries. * * @wm: WM97xx device to configure * @mode: WM97XX_PRP value to configure while suspended
*/ void wm97xx_set_suspend_mode(struct wm97xx *wm, u16 mode)
{
wm->suspend_mode = mode;
device_init_wakeup(&wm->input_dev->dev, mode != 0);
}
EXPORT_SYMBOL_GPL(wm97xx_set_suspend_mode);
/* do we need to enable the touch panel reader */ if (wm->id == WM9705_ID2) { if (wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD) &
WM97XX_PEN_DOWN)
wm->pen_is_down = 1; else
wm->pen_is_down = 0;
} else {
u16 status, pol;
mutex_lock(&wm->codec_mutex);
status = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
pol = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
if (WM97XX_GPIO_13 & pol & status) {
wm->pen_is_down = 1;
wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol &
~WM97XX_GPIO_13);
} else {
wm->pen_is_down = 0;
wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol |
WM97XX_GPIO_13);
}
/* If the system is not using continuous mode or it provides a * pen down operation then we need to schedule polls while the * pen is down. Otherwise the machine driver is responsible * for scheduling reads.
*/ if (!wm->mach_ops->acc_enabled || wm->mach_ops->acc_pen_down) { if (wm->pen_is_down && !pen_was_down) { /* Data is not available immediately on pen down */
queue_delayed_work(wm->ts_workq, &wm->ts_reader, 1);
}
/* Let ts_reader report the pen up for debounce. */ if (!wm->pen_is_down && pen_was_down)
wm->pen_is_down = 1;
}
if (!wm->pen_is_down && wm->mach_ops->acc_enabled)
wm->mach_ops->acc_pen_up(wm);
if (rc & RC_PENUP) { if (wm->pen_is_down) {
wm->pen_is_down = 0;
dev_dbg(wm->dev, "pen up\n");
input_report_abs(wm->input_dev, ABS_PRESSURE, 0);
input_report_key(wm->input_dev, BTN_TOUCH, 0);
input_sync(wm->input_dev);
} elseif (!(rc & RC_AGAIN)) { /* We need high frequency updates only while * pen is down, the user never will be able to * touch screen faster than a few times per * second... On the other hand, when the user * is actively working with the touchscreen we * don't want to lose the quick response. So we * will slowly increase sleep time after the * pen is up and quickly restore it to ~one task * switch when pen is down again.
*/ if (wm->ts_reader_interval < HZ / 10)
wm->ts_reader_interval++;
}
do {
rc = wm97xx_read_samples(wm);
} while (rc & RC_AGAIN);
if (wm->pen_is_down || !wm->pen_irq)
queue_delayed_work(wm->ts_workq, &wm->ts_reader,
wm->ts_reader_interval);
}
/** * wm97xx_ts_input_open - Open the touch screen input device. * @idev: Input device to be opened. * * Called by the input sub system to open a wm97xx touchscreen device. * Starts the touchscreen thread and touch digitiser.
*/ staticint wm97xx_ts_input_open(struct input_dev *idev)
{ struct wm97xx *wm = input_get_drvdata(idev);
wm->ts_workq = alloc_ordered_workqueue("kwm97xx", 0); if (wm->ts_workq == NULL) {
dev_err(wm->dev, "Failed to create workqueue\n"); return -EINVAL;
}
wm->pen_is_down = 0; if (wm->pen_irq)
wm97xx_init_pen_irq(wm); else
dev_err(wm->dev, "No IRQ specified\n");
/* If we either don't have an interrupt for pen down events or * failed to acquire it then we need to poll.
*/ if (wm->pen_irq == 0)
queue_delayed_work(wm->ts_workq, &wm->ts_reader,
wm->ts_reader_interval);
return 0;
}
/** * wm97xx_ts_input_close - Close the touch screen input device. * @idev: Input device to be closed. * * Called by the input sub system to close a wm97xx touchscreen * device. Kills the touchscreen thread and stops the touch * digitiser.
*/
/* check that we have a supported codec */
id = wm97xx_reg_read(wm, AC97_VENDOR_ID1); if (id != WM97XX_ID1) {
dev_err(wm->dev, "Device with vendor %04x is not a wm97xx\n", id); return -ENODEV;
}
wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2);
wm->variant = WM97xx_GENERIC;
dev_info(wm->dev, "detected a wm97%02x codec\n", wm->id & 0xff);
switch (wm->id & 0xff) { #ifdef CONFIG_TOUCHSCREEN_WM9705 case 0x05:
wm->codec = &wm9705_codec; break; #endif #ifdef CONFIG_TOUCHSCREEN_WM9712 case 0x12:
wm->codec = &wm9712_codec; break; #endif #ifdef CONFIG_TOUCHSCREEN_WM9713 case 0x13:
wm->codec = &wm9713_codec; break; #endif default:
dev_err(wm->dev, "Support for wm97%02x not compiled in.\n",
wm->id & 0xff); return -ENODEV;
}
/* set up physical characteristics */
wm->codec->phy_init(wm);
if (device_may_wakeup(&wm->input_dev->dev))
suspend_mode = wm->suspend_mode; else
suspend_mode = 0;
mutex_lock(&wm->input_dev->mutex); if (input_device_enabled(wm->input_dev))
cancel_delayed_work_sync(&wm->ts_reader);
/* Power down the digitiser (bypassing the cache for resume) */
reg = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER2);
reg &= ~WM97XX_PRP_DET_DIG; if (input_device_enabled(wm->input_dev))
reg |= suspend_mode;
wm->ac97->bus->ops->write(wm->ac97, AC97_WM97XX_DIGITISER2, reg);
/* WM9713 has an additional power bit - turn it off if there
* are no users or if suspend mode is zero. */ if (wm->id == WM9713_ID2 &&
(!input_device_enabled(wm->input_dev) || !suspend_mode)) {
reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) | 0x8000;
wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg);
}
mutex_unlock(&wm->input_dev->mutex);
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.