From patchwork Mon Jan 3 04:13:10 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Grahovac X-Patchwork-Id: 446741 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p034DOJ7022832 for ; Mon, 3 Jan 2011 04:13:24 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753845Ab1ACENW (ORCPT ); Sun, 2 Jan 2011 23:13:22 -0500 Received: from mail-vw0-f46.google.com ([209.85.212.46]:55704 "EHLO mail-vw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753653Ab1ACENW (ORCPT ); Sun, 2 Jan 2011 23:13:22 -0500 Received: by vws16 with SMTP id 16so5706272vws.19 for ; Sun, 02 Jan 2011 20:13:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references; bh=rYRIfsMvfDrnUN2ecW8EwcidEIRRilXZe88bLsGKUNU=; b=IU5rwKvEzHaZ8STCyXPlz2tjPPZDzd6QqXlK3jhktDZL3j/IVjyKr9uhDSjYhHBkzB IKcVvdA3LvRtfaAK6mpt6H6cI89CgtUB2cyBd8qVOP8m7vlxTQfALYJun0K7dmeq/rb+ nba9uXqQhIhVeLTMnsoxKFJT+qq2GXC2Dsn7E= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=wSzJqdRsUvGPl9VONpJD6gWd1LAJNux98K8bLaeg6hfNHl3A21QXo5Tf5G55hkeoyS Tm0G6IERAVISA3QkcEpI/9zMg2gTfrodVIRMBHp1B/lgQHnWXct3LtcXNuAlbM2S3yBs T3z6hdR2R8lFdkaB8z7jz95MbfPllG2qVYLsw= Received: by 10.220.190.71 with SMTP id dh7mr1172009vcb.201.1294027999784; Sun, 02 Jan 2011 20:13:19 -0800 (PST) Received: from linux-mint.wi.rr.com (cpe-174-102-164-27.wi.res.rr.com [174.102.164.27]) by mx.google.com with ESMTPS id b26sm7405812vby.3.2011.01.02.20.13.18 (version=SSLv3 cipher=RC4-MD5); Sun, 02 Jan 2011 20:13:19 -0800 (PST) From: Steve Grahovac To: linux-input@vger.kernel.org Cc: dmitry.torokhov@gmail.com, Steve Grahovac Subject: [PATCH 1/1] Added support for Microchip Projected Capacitive Touchscreen controllers for UART communications Date: Sun, 2 Jan 2011 22:13:10 -0600 Message-Id: <1294027991-2537-2-git-send-email-user@linux-mint> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1294027991-2537-1-git-send-email-user@linux-mint> References: <1294027991-2537-1-git-send-email-user@linux-mint> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Mon, 03 Jan 2011 04:13:25 +0000 (UTC) diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 400c99d..e69ec50 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -648,4 +648,14 @@ config TOUCHSCREEN_STMPE To compile this driver as a module, choose M here: the module will be called stmpe-ts. +config TOUCHSCREEN_MCHPPCAP + tristate "Microchip PCAP touchscreen" + select SERIO + help + Say Y here if you have a Microchip PCAP Controller and + want to enable support for the built-in touchscreen. + + To compile this driver as a module, choose M here: the + module will be called mchippcap. + endif diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 22e2d59..9575478 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -53,3 +53,4 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o +obj-$(CONFIG_TOUCHSCREEN_MCHPPCAP) += mchppcapmt.o diff --git a/drivers/input/touchscreen/mchppcapmt.c b/drivers/input/touchscreen/mchppcapmt.c new file mode 100755 index 0000000..047a4d0 --- /dev/null +++ b/drivers/input/touchscreen/mchppcapmt.c @@ -0,0 +1,263 @@ +/* + * Microchip Serial Touchscreen Driver + * + * Copyright (c) 2010 Microchip Technology, Inc. + * + * http://www.microchip.com/mtouch + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +/* + * This driver can handle serial Microchip controllers using the Projected + * Capacitive 5-byte protocol + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_DESC "Microchip Project Capacitive Serial Touchscreen Driver" + +MODULE_AUTHOR("Steve Grahovac "); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +/* + * Definitions & global arrays. + */ + +#define MCHIP_MAX_LENGTH 5 + +/* + * Per-touchscreen controller data. + */ + +struct mchip { + struct input_dev *dev; + struct serio *serio; + int id; + int index; + unsigned char data[MCHIP_MAX_LENGTH]; + char phys[32]; +}; + +static void mchppcap_process_data(struct mchip *mchip, unsigned char data) +{ + struct input_dev *dev = mchip->dev; + + mchip->data[mchip->index] = data; + + /**************************************************** + Data format, 5 bytes: SYNC, DATA1, DATA2, DATA3, DATA4 + SYNC [7:0]: 1,TOUCHID[6:5],0,0,TOUCHSTATUS[2:0] + DATA1[7:0]: 0,X-LOW[6:0] + DATA2[7:0]: 0,X-HIGH[2:0] + DATA3[7:0]: 0,Y-LOW[6:0] + DATA4[7:0]: 0,Y-HIGH[2:0] + TOUCHSTATUS: 0 = Touch up, 1 = Touch down + ****************************************************/ + switch (mchip->index++) { + case 0: + /* Verify if sync bit is set for the first byte of packet */ + if (!(0x80 & data)) + mchip->index = 0; + break; + + case (MCHIP_MAX_LENGTH - 1): + /* verify byte is valid for current index */ + if (0x80 & data) { + /* byte not valid */ + mchip->data[0] = data; + mchip->index = 1; + break; + } + + mchip->index = 0; + input_report_abs(dev, ABS_MT_TRACKING_ID, \ + (mchip->data[0]&0x60) >> 5); + input_report_abs(dev, ABS_MT_POSITION_X, \ + ((mchip->data[2] & 0x1f) << 7) | (mchip->data[1] & 0x7f)); + input_report_abs(dev, ABS_MT_POSITION_Y, \ + ((mchip->data[4] & 0x1f) << 7) | (mchip->data[3] & 0x7f)); + input_report_abs(dev, ABS_MT_TOUCH_MAJOR, \ + 255*(0 != (mchip->data[0] & 7))); + input_mt_sync(dev); + + /* touchscreen emulation for ID 0 */ + if (0 == ((mchip->data[0]&0x60) >> 5)) { + input_report_abs(dev, ABS_X, \ + ((mchip->data[2]&0x1f) << 7)|(mchip->data[1]&0x7f)); + input_report_abs(dev, ABS_Y, \ + ((mchip->data[4]&0x1f) << 7)|(mchip->data[3]&0x7f)); + input_report_key(dev, BTN_TOUCH, \ + 0 != (mchip->data[0] & 7)); + } + + input_sync(dev); + break; + default: + /* verify byte is valid for current index */ + if (0x80 & data) { + /* byte not valid */ + mchip->data[0] = data; + mchip->index = 1; + } + break; + } +} + + +static irqreturn_t mchppcap_interrupt(struct serio *serio, + unsigned char data, unsigned int flags) +{ + struct mchip *mchip = serio_get_drvdata(serio); + + mchppcap_process_data(mchip, data); + + return IRQ_HANDLED; +} + +static int mchppcap_setup(struct mchip *mchip) +{ + struct input_dev *dev = mchip->dev; + + input_set_abs_params(dev, ABS_X, 0, 1023, 0, 0); + input_set_abs_params(dev, ABS_Y, 0, 1023, 0, 0); + + input_set_abs_params(dev, ABS_MT_POSITION_X, 0, 1023, 0, 0); + input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, 1023, 0, 0); + input_set_abs_params(dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(dev, ABS_MT_TRACKING_ID, 0, 3, 0, 0); + + return 0; +} + +/* + * mchppcap_disconnect() is the opposite of mchppcap_connect() + */ + +static void mchppcap_disconnect(struct serio *serio) +{ + struct mchip *mchip = serio_get_drvdata(serio); + + input_get_device(mchip->dev); + input_unregister_device(mchip->dev); + serio_close(serio); + serio_set_drvdata(serio, NULL); + input_put_device(mchip->dev); + kfree(mchip); +} + +/* + * mchppcap_connect() is the routine that is called when someone adds a + * new serio device that supports PCAP protocol and registers it as + * an input device. + */ + +static int mchppcap_connect(struct serio *serio, struct serio_driver *drv) +{ + struct mchip *mchip; + struct input_dev *input_dev; + int err; + + mchip = kzalloc(sizeof(struct mchip), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!mchip || !input_dev) { + err = -ENOMEM; + goto fail1; + } + + mchip->serio = serio; + mchip->id = serio->id.id; + mchip->dev = input_dev; + snprintf(mchip->phys, sizeof(mchip->phys), "%s/input0", serio->phys); + + input_dev->name = "Microchip Serial TouchScreen"; + input_dev->phys = mchip->phys; + input_dev->id.bustype = BUS_RS232; + input_dev->id.vendor = SERIO_MCHPPCAP; + input_dev->id.product = mchip->id; + input_dev->id.version = 0x0100; + input_dev->dev.parent = &serio->dev; + + set_bit(EV_SYN, input_dev->evbit); + set_bit(EV_KEY, input_dev->evbit); + set_bit(BTN_TOUCH, input_dev->keybit); + set_bit(BTN_2, input_dev->keybit); + set_bit(EV_ABS, input_dev->evbit); + + serio_set_drvdata(serio, mchip); + + err = serio_open(serio, drv); + if (err) + goto fail2; + + + mchppcap_setup(mchip); + + err = input_register_device(mchip->dev); + if (err) + goto fail3; + + return 0; + +fail3: serio_close(serio); +fail2: serio_set_drvdata(serio, NULL); +fail1: input_free_device(input_dev); + kfree(mchip); + return err; +} + +/* + * The serio driver structure. + */ + +static struct serio_device_id mchppcap_serio_ids[] = { + { + .type = SERIO_RS232, + .proto = SERIO_MCHPPCAP, + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, + { 0 } +}; + +MODULE_DEVICE_TABLE(serio, mchppcap_serio_ids); + +static struct serio_driver mchppcap_drv = { + .driver = { + .name = "mchip", + }, + .description = DRIVER_DESC, + .id_table = mchppcap_serio_ids, + .interrupt = mchppcap_interrupt, + .connect = mchppcap_connect, + .disconnect = mchppcap_disconnect, +}; + +/* + * The functions for inserting/removing us as a module. + */ + +static int __init mchppcap_init(void) +{ + return serio_register_driver(&mchppcap_drv); +} + +static void __exit mchppcap_exit(void) +{ + serio_unregister_driver(&mchppcap_drv); +} + +module_init(mchppcap_init); +module_exit(mchppcap_exit); diff --git a/include/linux/serio.h b/include/linux/serio.h index b555256..3a7b8a9 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h @@ -197,5 +197,6 @@ static inline void serio_continue_rx(struct serio *serio) #define SERIO_W8001 0x39 #define SERIO_DYNAPRO 0x3a #define SERIO_HAMPSHIRE 0x3b +#define SERIO_MCHPPCAP 0x3d #endif