Example nodes:
- gpio_keys {
+ gpio-keys {
compatible = "gpio-keys";
- #address-cells = <1>;
- #size-cells = <0>;
autorepeat;
- button@21 {
+
+ up {
label = "GPIO Key UP";
linux,code = <103>;
gpios = <&gpio1 0 1>;
};
- button@22 {
+
+ down {
label = "GPIO Key DOWN";
linux,code = <108>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
Required properties:
- compatible: must be "brcm,iproc-touchscreen"
-- reg: physical base address of the controller and length of memory mapped
- region.
+- ts_syscon: handler of syscon node defining physical base
+ address of the controller and length of memory mapped region.
+ If this property is selected please make sure MFD_SYSCON config
+ is enabled in the defconfig file.
- clocks: The clock provided by the SOC to driver the tsc
-- clock-name: name for the clock
+- clock-names: name for the clock
- interrupts: The touchscreen controller's interrupt
+- address-cells: Specify the number of u32 entries needed in child nodes.
+ Should set to 1.
+- size-cells: Specify number of u32 entries needed to specify child nodes size
+ in reg property. Should set to 1.
Optional properties:
- scanning_period: Time between scans. Each step is 1024 us. Valid 1-256.
- touchscreen-inverted-x: X axis is inverted (boolean)
- touchscreen-inverted-y: Y axis is inverted (boolean)
-Example:
+Example: An example of touchscreen node
- touchscreen: tsc@0x180A6000 {
+ ts_adc_syscon: ts_adc_syscon@180a6000 {
+ compatible = "brcm,iproc-ts-adc-syscon","syscon";
+ reg = <0x180a6000 0xc30>;
+ };
+
+ touchscreen: touchscreen@180A6000 {
compatible = "brcm,iproc-touchscreen";
#address-cells = <1>;
#size-cells = <1>;
- reg = <0x180A6000 0x40>;
+ ts_syscon = <&ts_adc_syscon>;
clocks = <&adc_clk>;
clock-names = "tsc_clk";
interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
<&pinctrl 142 10 1>;
};
- touchscreen: tsc@180a6000 {
+ ts_adc_syscon: ts_adc_syscon@180a6000 {
+ compatible = "brcm,iproc-ts-adc-syscon", "syscon";
+ reg = <0x180a6000 0xc30>;
+ };
+
+ touchscreen: touchscreen@180a6000 {
compatible = "brcm,iproc-touchscreen";
- reg = <0x180a6000 0x40>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ts_syscon = <&ts_adc_syscon>;
clocks = <&asiu_clks BCM_CYGNUS_ASIU_ADC_CLK>;
clock-names = "tsc_clk";
interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
static unsigned int *row_gpios;
static unsigned int *col_gpios;
-#ifdef CONFIG_ARCH_OMAP2
-static void set_col_gpio_val(struct omap_kp *omap_kp, u8 value)
-{
- int col;
-
- for (col = 0; col < omap_kp->cols; col++)
- gpio_set_value(col_gpios[col], value & (1 << col));
-}
-
-static u8 get_row_gpio_val(struct omap_kp *omap_kp)
-{
- int row;
- u8 value = 0;
-
- for (row = 0; row < omap_kp->rows; row++) {
- if (gpio_get_value(row_gpios[row]))
- value |= (1 << row);
- }
- return value;
-}
-#else
-#define set_col_gpio_val(x, y) do {} while (0)
-#define get_row_gpio_val(x) 0
-#endif
-
static irqreturn_t omap_kp_interrupt(int irq, void *dev_id)
{
/* disable keyboard interrupt and schedule for handling */
unsigned int row_shift = get_count_order(omap_kp_data->cols);
unsigned char new_state[8], changed, key_down = 0;
int col, row;
- int spurious = 0;
/* check for any changes */
omap_kp_scan_keypad(omap_kp_data, new_state);
memcpy(keypad_state, new_state, sizeof(keypad_state));
if (key_down) {
- int delay = HZ / 20;
/* some key is pressed - keep irq disabled and use timer
* to poll the keypad */
- if (spurious)
- delay = 2 * HZ;
- mod_timer(&omap_kp_data->timer, jiffies + delay);
+ mod_timer(&omap_kp_data->timer, jiffies + HZ / 20);
} else {
/* enable interrupts */
omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, omap_kp_enable_show, omap_kp_enable_store);
-#ifdef CONFIG_PM
-static int omap_kp_suspend(struct platform_device *dev, pm_message_t state)
-{
- /* Nothing yet */
-
- return 0;
-}
-
-static int omap_kp_resume(struct platform_device *dev)
-{
- /* Nothing yet */
-
- return 0;
-}
-#else
-#define omap_kp_suspend NULL
-#define omap_kp_resume NULL
-#endif
-
static int omap_kp_probe(struct platform_device *pdev)
{
struct omap_kp *omap_kp;
static struct platform_driver omap_kp_driver = {
.probe = omap_kp_probe,
.remove = omap_kp_remove,
- .suspend = omap_kp_suspend,
- .resume = omap_kp_resume,
.driver = {
.name = "omap-keypad",
},
unsigned short keymap[TWL4030_KEYMAP_SIZE];
u16 kp_state[TWL4030_MAX_ROWS];
bool autorepeat;
- unsigned n_rows;
- unsigned n_cols;
- unsigned irq;
+ unsigned int n_rows;
+ unsigned int n_cols;
+ unsigned int irq;
struct device *dbg_dev;
struct input_dev *input;
#define KEYP_CTRL_KBD_ON BIT(6)
/* KEYP_DEB, KEYP_LONG_KEY, KEYP_TIMEOUT_x*/
-#define KEYP_PERIOD_US(t, prescale) ((t) / (31 << (prescale + 1)) - 1)
+#define KEYP_PERIOD_US(t, prescale) ((t) / (31 << ((prescale) + 1)) - 1)
/* KEYP_LK_PTV_REG Fields */
#define KEYP_LK_PTV_PTV_SHIFT 5
static inline u16 twl4030_col_xlate(struct twl4030_keypad *kp, u8 col)
{
- /* If all bits in a row are active for all coloumns then
+ /*
+ * If all bits in a row are active for all columns then
* we have that row line connected to gnd. Mark this
- * key on as if it was on matrix position n_cols (ie
+ * key on as if it was on matrix position n_cols (i.e.
* one higher than the size of the matrix).
*/
if (col == 0xFF)
u16 new_state[TWL4030_MAX_ROWS];
int col, row;
- if (release_all)
+ if (release_all) {
memset(new_state, 0, sizeof(new_state));
- else {
+ } else {
/* check for any changes */
int ret = twl4030_read_kp_matrix_state(kp, new_state);
/* Read & Clear TWL4030 pending interrupt */
ret = twl4030_kpread(kp, ®, KEYP_ISR1, 1);
- /* Release all keys if I2C has gone bad or
- * the KEYP has gone to idle state */
+ /*
+ * Release all keys if I2C has gone bad or
+ * the KEYP has gone to idle state.
+ */
if (ret >= 0 && (reg & KEYP_IMR1_KP))
twl4030_kp_scan(kp, false);
else
if (twl4030_kpwrite_u8(kp, reg, KEYP_CTRL) < 0)
return -EIO;
- /* NOTE: we could use sih_setup() here to package keypad
+ /*
+ * NOTE: we could use sih_setup() here to package keypad
* event sources as four different IRQs ... but we don't.
*/
/*
* Enable Clear-on-Read; disable remembering events that fire
- * after the IRQ but before our handler acks (reads) them,
+ * after the IRQ but before our handler acks (reads) them.
*/
reg = TWL4030_SIH_CTRL_COR_MASK | TWL4030_SIH_CTRL_PENDDIS_MASK;
if (twl4030_kpwrite_u8(kp, reg, KEYP_SIH_CTRL) < 0)
BUZZER_ON = 1 << 5,
- /* up to 256 normal keys, up to 16 special keys */
- KEYMAP_SIZE = 256 + 16,
+ /* up to 256 normal keys, up to 15 special key combinations */
+ KEYMAP_SIZE = 256 + 15,
};
/* CM109 protocol packet */
{
if (code > 0xff) {
switch (code - 0xff) {
- case RECORD_MUTE: return KEY_MUTE;
+ case RECORD_MUTE: return KEY_MICMUTE;
case PLAYBACK_MUTE: return KEY_MUTE;
case VOLUME_DOWN: return KEY_VOLUMEDOWN;
case VOLUME_UP: return KEY_VOLUMEUP;
input_sync(idev);
}
+/*
+ * Converts data of special key presses (volume, mute) into events
+ * for the input subsystem, sends press-n-release for mute keys.
+ */
+static void cm109_report_special(struct cm109_dev *dev)
+{
+ static const u8 autorelease = RECORD_MUTE | PLAYBACK_MUTE;
+ struct input_dev *idev = dev->idev;
+ u8 data = dev->irq_data->byte[HID_IR0];
+ unsigned short keycode;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ keycode = dev->keymap[0xff + BIT(i)];
+ if (keycode == KEY_RESERVED)
+ continue;
+
+ input_report_key(idev, keycode, data & BIT(i));
+ if (data & autorelease & BIT(i)) {
+ input_sync(idev);
+ input_report_key(idev, keycode, 0);
+ }
+ }
+ input_sync(idev);
+}
+
/******************************************************************************
* CM109 usb communication interface
*****************************************************************************/
struct cm109_dev *dev = urb->context;
const int status = urb->status;
int error;
+ unsigned long flags;
dev_dbg(&dev->intf->dev, "### URB IRQ: [0x%02x 0x%02x 0x%02x 0x%02x] keybit=0x%02x\n",
dev->irq_data->byte[0],
}
/* Special keys */
- if (dev->irq_data->byte[HID_IR0] & 0x0f) {
- const int code = (dev->irq_data->byte[HID_IR0] & 0x0f);
- report_key(dev, dev->keymap[0xff + code]);
- }
+ cm109_report_special(dev);
/* Scan key column */
if (dev->keybit == 0xf) {
out:
- spin_lock(&dev->ctl_submit_lock);
+ spin_lock_irqsave(&dev->ctl_submit_lock, flags);
dev->irq_urb_pending = 0;
__func__, error);
}
- spin_unlock(&dev->ctl_submit_lock);
+ spin_unlock_irqrestore(&dev->ctl_submit_lock, flags);
}
static void cm109_urb_ctl_callback(struct urb *urb)
struct cm109_dev *dev = urb->context;
const int status = urb->status;
int error;
+ unsigned long flags;
dev_dbg(&dev->intf->dev, "### URB CTL: [0x%02x 0x%02x 0x%02x 0x%02x]\n",
dev->ctl_data->byte[0],
__func__, status);
}
- spin_lock(&dev->ctl_submit_lock);
+ spin_lock_irqsave(&dev->ctl_submit_lock, flags);
dev->ctl_urb_pending = 0;
}
}
- spin_unlock(&dev->ctl_submit_lock);
+ spin_unlock_irqrestore(&dev->ctl_submit_lock, flags);
}
static void cm109_toggle_buzzer_async(struct cm109_dev *dev)
bool armed;
signed char dir; /* 1 - clockwise, -1 - CCW */
- unsigned last_stable;
+ unsigned int last_stable;
};
-static unsigned rotary_encoder_get_state(struct rotary_encoder *encoder)
+static unsigned int rotary_encoder_get_state(struct rotary_encoder *encoder)
{
int i;
- unsigned ret = 0;
+ unsigned int ret = 0;
for (i = 0; i < encoder->gpios->ndescs; ++i) {
int val = gpiod_get_value_cansleep(encoder->gpios->desc[i]);
static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
{
struct rotary_encoder *encoder = dev_id;
- unsigned state;
+ unsigned int state;
mutex_lock(&encoder->access_mutex);
struct device *dev;
struct input_dev *input_dev;
struct work_struct play_work;
- struct mutex mutex;
+
int irq;
bool enabled;
return;
}
- mutex_lock(&info->mutex);
-
if (info->weak_speed || info->strong_speed) {
if (!info->enabled)
twl6040_vibra_enable(info);
} else if (info->enabled)
twl6040_vibra_disable(info);
- mutex_unlock(&info->mutex);
}
static int vibra_play(struct input_dev *input, void *data,
cancel_work_sync(&info->play_work);
- mutex_lock(&info->mutex);
-
if (info->enabled)
twl6040_vibra_disable(info);
-
- mutex_unlock(&info->mutex);
}
static int __maybe_unused twl6040_vibra_suspend(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct vibra_info *info = platform_get_drvdata(pdev);
- mutex_lock(&info->mutex);
+ cancel_work_sync(&info->play_work);
if (info->enabled)
twl6040_vibra_disable(info);
- mutex_unlock(&info->mutex);
-
return 0;
}
return -EINVAL;
}
- mutex_init(&info->mutex);
-
error = devm_request_threaded_irq(&pdev->dev, info->irq, NULL,
twl6040_vib_irq_handler,
IRQF_ONESHOT,
if (!priv)
return -ENOMEM;
- memset(priv, 0, sizeof(*priv));
setup_timer(&priv->timer, byd_clear_touch, (unsigned long) psmouse);
psmouse->private = priv;
struct usb_acecad {
char name[128];
char phys[64];
- struct usb_device *usbdev;
struct usb_interface *intf;
struct input_dev *input;
struct urb *irq;
unsigned char *data = acecad->data;
struct input_dev *dev = acecad->input;
struct usb_interface *intf = acecad->intf;
+ struct usb_device *udev = interface_to_usbdev(intf);
int prox, status;
switch (urb->status) {
if (status)
dev_err(&intf->dev,
"can't resubmit intr, %s-%s/input0, status %d\n",
- acecad->usbdev->bus->bus_name,
- acecad->usbdev->devpath, status);
+ udev->bus->bus_name,
+ udev->devpath, status);
}
static int usb_acecad_open(struct input_dev *dev)
{
struct usb_acecad *acecad = input_get_drvdata(dev);
- acecad->irq->dev = acecad->usbdev;
+ acecad->irq->dev = interface_to_usbdev(acecad->intf);
if (usb_submit_urb(acecad->irq, GFP_KERNEL))
return -EIO;
goto fail2;
}
- acecad->usbdev = dev;
acecad->intf = intf;
acecad->input = input_dev;
static void usb_acecad_disconnect(struct usb_interface *intf)
{
struct usb_acecad *acecad = usb_get_intfdata(intf);
+ struct usb_device *udev = interface_to_usbdev(intf);
usb_set_intfdata(intf, NULL);
input_unregister_device(acecad->input);
usb_free_urb(acecad->irq);
- usb_free_coherent(acecad->usbdev, 8, acecad->data, acecad->data_dma);
+ usb_free_coherent(udev, 8, acecad->data, acecad->data_dma);
kfree(acecad);
}
struct aiptek {
struct input_dev *inputdev; /* input device struct */
- struct usb_device *usbdev; /* usb device struct */
struct usb_interface *intf; /* usb interface struct */
struct urb *urb; /* urb for incoming reports */
dma_addr_t data_dma; /* our dma stuffage */
{
struct aiptek *aiptek = input_get_drvdata(inputdev);
- aiptek->urb->dev = aiptek->usbdev;
+ aiptek->urb->dev = interface_to_usbdev(aiptek->intf);
if (usb_submit_urb(aiptek->urb, GFP_KERNEL) != 0)
return -EIO;
unsigned char report_type,
unsigned char report_id, void *buffer, int size)
{
- return usb_control_msg(aiptek->usbdev,
- usb_sndctrlpipe(aiptek->usbdev, 0),
+ struct usb_device *udev = interface_to_usbdev(aiptek->intf);
+
+ return usb_control_msg(udev,
+ usb_sndctrlpipe(udev, 0),
USB_REQ_SET_REPORT,
USB_TYPE_CLASS | USB_RECIP_INTERFACE |
USB_DIR_OUT, (report_type << 8) + report_id,
unsigned char report_type,
unsigned char report_id, void *buffer, int size)
{
- return usb_control_msg(aiptek->usbdev,
- usb_rcvctrlpipe(aiptek->usbdev, 0),
+ struct usb_device *udev = interface_to_usbdev(aiptek->intf);
+
+ return usb_control_msg(udev,
+ usb_rcvctrlpipe(udev, 0),
USB_REQ_GET_REPORT,
USB_TYPE_CLASS | USB_RECIP_INTERFACE |
USB_DIR_IN, (report_type << 8) + report_id,
}
aiptek->inputdev = inputdev;
- aiptek->usbdev = usbdev;
aiptek->intf = intf;
aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber;
aiptek->inDelay = 0;
* input.
*/
usb_fill_int_urb(aiptek->urb,
- aiptek->usbdev,
- usb_rcvintpipe(aiptek->usbdev,
+ usbdev,
+ usb_rcvintpipe(usbdev,
endpoint->bEndpointAddress),
aiptek->data, 8, aiptek_irq, aiptek,
endpoint->bInterval);
struct gtco {
struct input_dev *inputdevice; /* input device struct pointer */
- struct usb_device *usbdev; /* the usb device for this device */
struct usb_interface *intf; /* the usb interface for this device */
struct urb *urbinfo; /* urb for incoming reports */
dma_addr_t buf_dma; /* dma addr of the data buffer*/
{
struct gtco *device = input_get_drvdata(inputdev);
- device->urbinfo->dev = device->usbdev;
+ device->urbinfo->dev = interface_to_usbdev(device->intf);
if (usb_submit_urb(device->urbinfo, GFP_KERNEL))
return -EIO;
int result = 0, retry;
int error;
struct usb_endpoint_descriptor *endpoint;
+ struct usb_device *udev = interface_to_usbdev(usbinterface);
/* Allocate memory for device structure */
gtco = kzalloc(sizeof(struct gtco), GFP_KERNEL);
gtco->inputdevice = input_dev;
/* Save interface information */
- gtco->usbdev = interface_to_usbdev(usbinterface);
gtco->intf = usbinterface;
/* Allocate some data for incoming reports */
- gtco->buffer = usb_alloc_coherent(gtco->usbdev, REPORT_MAX_SIZE,
+ gtco->buffer = usb_alloc_coherent(udev, REPORT_MAX_SIZE,
GFP_KERNEL, >co->buf_dma);
if (!gtco->buffer) {
dev_err(&usbinterface->dev, "No more memory for us buffers\n");
/* Couple of tries to get reply */
for (retry = 0; retry < 3; retry++) {
- result = usb_control_msg(gtco->usbdev,
- usb_rcvctrlpipe(gtco->usbdev, 0),
+ result = usb_control_msg(udev,
+ usb_rcvctrlpipe(udev, 0),
USB_REQ_GET_DESCRIPTOR,
USB_RECIP_INTERFACE | USB_DIR_IN,
REPORT_DEVICE_TYPE << 8,
}
/* Create a device file node */
- usb_make_path(gtco->usbdev, gtco->usbpath, sizeof(gtco->usbpath));
+ usb_make_path(udev, gtco->usbpath, sizeof(gtco->usbpath));
strlcat(gtco->usbpath, "/input0", sizeof(gtco->usbpath));
/* Set Input device functions */
gtco_setup_caps(input_dev);
/* Set input device required ID information */
- usb_to_input_id(gtco->usbdev, &input_dev->id);
+ usb_to_input_id(udev, &input_dev->id);
input_dev->dev.parent = &usbinterface->dev;
/* Setup the URB, it will be posted later on open of input device */
endpoint = &usbinterface->altsetting[0].endpoint[0].desc;
usb_fill_int_urb(gtco->urbinfo,
- gtco->usbdev,
- usb_rcvintpipe(gtco->usbdev,
+ udev,
+ usb_rcvintpipe(udev,
endpoint->bEndpointAddress),
gtco->buffer,
REPORT_MAX_SIZE,
err_free_urb:
usb_free_urb(gtco->urbinfo);
err_free_buf:
- usb_free_coherent(gtco->usbdev, REPORT_MAX_SIZE,
+ usb_free_coherent(udev, REPORT_MAX_SIZE,
gtco->buffer, gtco->buf_dma);
err_free_devs:
input_free_device(input_dev);
{
/* Grab private device ptr */
struct gtco *gtco = usb_get_intfdata(interface);
+ struct usb_device *udev = interface_to_usbdev(interface);
/* Now reverse all the registration stuff */
if (gtco) {
input_unregister_device(gtco->inputdevice);
usb_kill_urb(gtco->urbinfo);
usb_free_urb(gtco->urbinfo);
- usb_free_coherent(gtco->usbdev, REPORT_MAX_SIZE,
+ usb_free_coherent(udev, REPORT_MAX_SIZE,
gtco->buffer, gtco->buf_dma);
kfree(gtco);
}
unsigned char *data;
dma_addr_t data_dma;
struct input_dev *dev;
- struct usb_device *usbdev;
struct usb_interface *intf;
struct urb *irq;
char phys[32];
static int kbtab_open(struct input_dev *dev)
{
struct kbtab *kbtab = input_get_drvdata(dev);
+ struct usb_device *udev = interface_to_usbdev(kbtab->intf);
- kbtab->irq->dev = kbtab->usbdev;
+ kbtab->irq->dev = udev;
if (usb_submit_urb(kbtab->irq, GFP_KERNEL))
return -EIO;
if (!kbtab->irq)
goto fail2;
- kbtab->usbdev = dev;
kbtab->intf = intf;
kbtab->dev = input_dev;
static void kbtab_disconnect(struct usb_interface *intf)
{
struct kbtab *kbtab = usb_get_intfdata(intf);
+ struct usb_device *udev = interface_to_usbdev(intf);
usb_set_intfdata(intf, NULL);
input_unregister_device(kbtab->dev);
usb_free_urb(kbtab->irq);
- usb_free_coherent(kbtab->usbdev, 8, kbtab->data, kbtab->data_dma);
+ usb_free_coherent(udev, 8, kbtab->data, kbtab->data_dma);
kfree(kbtab);
}
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/serio.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
#define IPROC_TS_NAME "iproc-ts"
#define TS_WIRE_MODE_BIT BIT(1)
#define dbg_reg(dev, priv, reg) \
- dev_dbg(dev, "%20s= 0x%08x\n", #reg, readl((priv)->regs + reg))
+do { \
+ u32 val; \
+ regmap_read(priv->regmap, reg, &val); \
+ dev_dbg(dev, "%20s= 0x%08x\n", #reg, val); \
+} while (0)
struct tsc_param {
/* Each step is 1024 us. Valid 1-256 */
struct platform_device *pdev;
struct input_dev *idev;
- void __iomem *regs;
+ struct regmap *regmap;
struct clk *tsc_clk;
int pen_status;
int i;
bool needs_sync = false;
- intr_status = readl(priv->regs + INTERRUPT_STATUS);
+ regmap_read(priv->regmap, INTERRUPT_STATUS, &intr_status);
intr_status &= TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK;
if (intr_status == 0)
return IRQ_NONE;
/* Clear all interrupt status bits, write-1-clear */
- writel(intr_status, priv->regs + INTERRUPT_STATUS);
-
+ regmap_write(priv->regmap, INTERRUPT_STATUS, intr_status);
/* Pen up/down */
if (intr_status & TS_PEN_INTR_MASK) {
- if (readl(priv->regs + CONTROLLER_STATUS) & TS_PEN_DOWN)
+ regmap_read(priv->regmap, CONTROLLER_STATUS, &priv->pen_status);
+ if (priv->pen_status & TS_PEN_DOWN)
priv->pen_status = PEN_DOWN_STATUS;
else
priv->pen_status = PEN_UP_STATUS;
- input_report_key(priv->idev, BTN_TOUCH, priv->pen_status);
+ input_report_key(priv->idev, BTN_TOUCH, priv->pen_status);
needs_sync = true;
dev_dbg(&priv->pdev->dev,
/* coordinates in FIFO exceed the theshold */
if (intr_status & TS_FIFO_INTR_MASK) {
for (i = 0; i < priv->cfg_params.fifo_threshold; i++) {
- raw_coordinate = readl(priv->regs + FIFO_DATA);
+ regmap_read(priv->regmap, FIFO_DATA, &raw_coordinate);
if (raw_coordinate == INVALID_COORD)
continue;
x = (x >> 4) & 0x0FFF;
y = (y >> 4) & 0x0FFF;
- /* adjust x y according to lcd tsc mount angle */
+ /* Adjust x y according to LCD tsc mount angle. */
if (priv->cfg_params.invert_x)
x = priv->cfg_params.max_x - x;
static int iproc_ts_start(struct input_dev *idev)
{
- struct iproc_ts_priv *priv = input_get_drvdata(idev);
u32 val;
+ u32 mask;
int error;
+ struct iproc_ts_priv *priv = input_get_drvdata(idev);
/* Enable clock */
error = clk_prepare_enable(priv->tsc_clk);
* FIFO reaches the int_th value, and pen event(up/down)
*/
val = TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK;
- writel(val, priv->regs + INTERRUPT_MASK);
+ regmap_update_bits(priv->regmap, INTERRUPT_MASK, val, val);
- writel(priv->cfg_params.fifo_threshold, priv->regs + INTERRUPT_THRES);
+ val = priv->cfg_params.fifo_threshold;
+ regmap_write(priv->regmap, INTERRUPT_THRES, val);
/* Initialize control reg1 */
val = 0;
val |= priv->cfg_params.debounce_timeout << DEBOUNCE_TIMEOUT_SHIFT;
val |= priv->cfg_params.settling_timeout << SETTLING_TIMEOUT_SHIFT;
val |= priv->cfg_params.touch_timeout << TOUCH_TIMEOUT_SHIFT;
- writel(val, priv->regs + REGCTL1);
+ regmap_write(priv->regmap, REGCTL1, val);
/* Try to clear all interrupt status */
- val = readl(priv->regs + INTERRUPT_STATUS);
- val |= TS_FIFO_INTR_MASK | TS_PEN_INTR_MASK;
- writel(val, priv->regs + INTERRUPT_STATUS);
+ val = TS_FIFO_INTR_MASK | TS_PEN_INTR_MASK;
+ regmap_update_bits(priv->regmap, INTERRUPT_STATUS, val, val);
/* Initialize control reg2 */
- val = readl(priv->regs + REGCTL2);
- val |= TS_CONTROLLER_EN_BIT | TS_WIRE_MODE_BIT;
-
- val &= ~TS_CONTROLLER_AVGDATA_MASK;
+ val = TS_CONTROLLER_EN_BIT | TS_WIRE_MODE_BIT;
val |= priv->cfg_params.average_data << TS_CONTROLLER_AVGDATA_SHIFT;
- val &= ~(TS_CONTROLLER_PWR_LDO | /* PWR up LDO */
+ mask = (TS_CONTROLLER_AVGDATA_MASK);
+ mask |= (TS_CONTROLLER_PWR_LDO | /* PWR up LDO */
TS_CONTROLLER_PWR_ADC | /* PWR up ADC */
TS_CONTROLLER_PWR_BGP | /* PWR up BGP */
TS_CONTROLLER_PWR_TS); /* PWR up TS */
-
- writel(val, priv->regs + REGCTL2);
+ mask |= val;
+ regmap_update_bits(priv->regmap, REGCTL2, mask, val);
ts_reg_dump(priv);
u32 val;
struct iproc_ts_priv *priv = input_get_drvdata(dev);
- writel(0, priv->regs + INTERRUPT_MASK); /* Disable all interrupts */
+ /*
+ * Disable FIFO int_th and pen event(up/down)Interrupts only
+ * as the interrupt mask register is shared between ADC, TS and
+ * flextimer.
+ */
+ val = TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK;
+ regmap_update_bits(priv->regmap, INTERRUPT_MASK, val, 0);
/* Only power down touch screen controller */
- val = readl(priv->regs + REGCTL2);
- val |= TS_CONTROLLER_PWR_TS;
- writel(val, priv->regs + REGCTL2);
+ val = TS_CONTROLLER_PWR_TS;
+ regmap_update_bits(priv->regmap, REGCTL2, val, val);
clk_disable(priv->tsc_clk);
}
{
struct iproc_ts_priv *priv;
struct input_dev *idev;
- struct resource *res;
int irq;
int error;
if (!priv)
return -ENOMEM;
- /* touchscreen controller memory mapped regs */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->regs = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(priv->regs)) {
- error = PTR_ERR(priv->regs);
- dev_err(&pdev->dev, "unable to map I/O memory: %d\n", error);
+ /* touchscreen controller memory mapped regs via syscon*/
+ priv->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+ "ts_syscon");
+ if (IS_ERR(priv->regmap)) {
+ error = PTR_ERR(priv->regmap);
+ dev_err(&pdev->dev, "unable to map I/O memory:%d\n", error);
return error;
}
return 0;
}
-#ifdef CONFIG_PM
-static int titsc_suspend(struct device *dev)
+static int __maybe_unused titsc_suspend(struct device *dev)
{
struct titsc *ts_dev = dev_get_drvdata(dev);
struct ti_tscadc_dev *tscadc_dev;
return 0;
}
-static int titsc_resume(struct device *dev)
+static int __maybe_unused titsc_resume(struct device *dev)
{
struct titsc *ts_dev = dev_get_drvdata(dev);
struct ti_tscadc_dev *tscadc_dev;
return 0;
}
-static const struct dev_pm_ops titsc_pm_ops = {
- .suspend = titsc_suspend,
- .resume = titsc_resume,
-};
-#define TITSC_PM_OPS (&titsc_pm_ops)
-#else
-#define TITSC_PM_OPS NULL
-#endif
+static SIMPLE_DEV_PM_OPS(titsc_pm_ops, titsc_suspend, titsc_resume);
static const struct of_device_id ti_tsc_dt_ids[] = {
{ .compatible = "ti,am3359-tsc", },
.remove = titsc_remove,
.driver = {
.name = "TI-am335x-tsc",
- .pm = TITSC_PM_OPS,
+ .pm = &titsc_pm_ops,
.of_match_table = ti_tsc_dt_ids,
},
};