12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342 |
- /*
- * Atmel maXTouch Touchscreen Controller Driver
- *
- *
- * Copyright (C) 2010 Atmel Corporation
- * Copyright (C) 2010 Ulf Samuelsson (ulf@atmel.com)
- * Copyright (C) 2009 Raphael Derosso Pereira <raphaelpereira@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- /*
- *
- * Driver for Atmel maXTouch family of touch controllers.
- *
- */
- #include <linux/i2c.h>
- #include <linux/interrupt.h>
- #include <linux/input.h>
- #include <linux/debugfs.h>
- #include <linux/cdev.h>
- #include <linux/mutex.h>
- #include <linux/slab.h>
- #include <linux/pm_runtime.h>
- #include <linux/module.h>
- #include <asm/uaccess.h>
- #include <linux/atmel_maxtouch.h>
- #if defined(CONFIG_HAS_EARLYSUSPEND)
- #include <linux/earlysuspend.h>
- /* Early-suspend level */
- #define MXT_SUSPEND_LEVEL 1
- #endif
- #define DRIVER_VERSION "0.91a_mod"
- static int debug = DEBUG_INFO;
- static int comms = 0;
- module_param(debug, int, 0644);
- module_param(comms, int, 0644);
- MODULE_PARM_DESC(debug, "Activate debugging output");
- MODULE_PARM_DESC(comms, "Select communications mode");
- #define T7_DATA_SIZE 3
- /* Device Info descriptor */
- /* Parsed from maXTouch "Id information" inside device */
- struct mxt_device_info {
- u8 family_id;
- u8 variant_id;
- u8 major;
- u8 minor;
- u8 build;
- u8 num_objs;
- u8 x_size;
- u8 y_size;
- char family_name[16]; /* Family name */
- char variant_name[16]; /* Variant name */
- u16 num_nodes; /* Number of sensor nodes */
- };
- /* object descriptor table, parsed from maXTouch "object table" */
- struct mxt_object {
- u16 chip_addr;
- u8 type;
- u8 size;
- u8 instances;
- u8 num_report_ids;
- };
- /* Mapping from report id to object type and instance */
- struct report_id_map {
- u8 object;
- u8 instance;
- /*
- * This is the first report ID belonging to object. It enables us to
- * find out easily the touch number: each touch has different report
- * ID (which are assigned to touches in increasing order). By
- * subtracting the first report ID from current, we get the touch
- * number.
- */
- u8 first_rid;
- };
- /* Driver datastructure */
- struct mxt_data {
- struct i2c_client *client;
- struct input_dev *input;
- char phys_name[32];
- int irq;
- u16 last_read_addr;
- bool new_msgs;
- u8 *last_message;
- int valid_irq_counter;
- int invalid_irq_counter;
- int irq_counter;
- int message_counter;
- int read_fail_counter;
- int bytes_to_read;
- struct delayed_work dwork;
- u8 xpos_format;
- u8 ypos_format;
- u8 numtouch;
- struct mxt_device_info device_info;
- u32 info_block_crc;
- u32 configuration_crc;
- u16 report_id_count;
- struct report_id_map *rid_map;
- struct mxt_object *object_table;
- u16 msg_proc_addr;
- u8 message_size;
- u16 min_x_val;
- u16 min_y_val;
- u16 max_x_val;
- u16 max_y_val;
- int (*init_hw)(struct i2c_client *client);
- int (*exit_hw)(struct i2c_client *client);
- int (*power_on)(bool on);
- u8 (*valid_interrupt)(void);
- u8 (*read_chg)(void);
- /* debugfs variables */
- struct dentry *debug_dir;
- int current_debug_datap;
- struct mutex debug_mutex;
- u16 *debug_data;
- /* Character device variables */
- struct cdev cdev;
- struct cdev cdev_messages; /* 2nd Char dev for messages */
- dev_t dev_num;
- struct class *mxt_class;
- u16 address_pointer;
- bool valid_ap;
- /* Message buffer & pointers */
- char *messages;
- int msg_buffer_startp, msg_buffer_endp;
- /* Put only non-touch messages to buffer if this is set */
- char nontouch_msg_only;
- struct mutex msg_mutex;
- #if defined(CONFIG_HAS_EARLYSUSPEND)
- struct early_suspend early_suspend;
- #endif
- u8 t7_data[T7_DATA_SIZE];
- bool is_suspended;
- };
- /*default value, enough to read versioning*/
- #define CONFIG_DATA_SIZE 6
- static u16 t38_size = CONFIG_DATA_SIZE;
- static int mxt_read_block(struct i2c_client *client, u16 addr, u16 length,
- u8 *value);
- static int mxt_write_byte(struct i2c_client *client, u16 addr, u8 value);
- static int mxt_write_block(struct i2c_client *client, u16 addr, u16 length,
- u8 *value);
- static u8 mxt_valid_interrupt_dummy(void)
- {
- return 1;
- }
- #define I2C_RETRY_COUNT 5
- #define I2C_PAYLOAD_SIZE 254
- /* Returns the start address of object in mXT memory. */
- #define MXT_BASE_ADDR(object_type, mxt) \
- get_object_address(object_type, 0, mxt->object_table, \
- mxt->device_info.num_objs)
- /* Maps a report ID to an object type (object type number). */
- #define REPORT_ID_TO_OBJECT(rid, mxt) \
- (((rid) == 0xff) ? 0 : mxt->rid_map[rid].object)
- /* Maps a report ID to an object type (string). */
- #define REPORT_ID_TO_OBJECT_NAME(rid, mxt) \
- object_type_name[REPORT_ID_TO_OBJECT(rid, mxt)]
- /* Returns non-zero if given object is a touch object */
- #define IS_TOUCH_OBJECT(object) \
- ((object == MXT_TOUCH_MULTITOUCHSCREEN_T9) || \
- (object == MXT_TOUCH_KEYARRAY_T15) || \
- (object == MXT_TOUCH_PROXIMITY_T23) || \
- (object == MXT_TOUCH_SINGLETOUCHSCREEN_T10) || \
- (object == MXT_TOUCH_XSLIDER_T11) || \
- (object == MXT_TOUCH_YSLIDER_T12) || \
- (object == MXT_TOUCH_XWHEEL_T13) || \
- (object == MXT_TOUCH_YWHEEL_T14) || \
- (object == MXT_TOUCH_KEYSET_T31) || \
- (object == MXT_TOUCH_XSLIDERSET_T32) ? 1 : 0)
- #define mxt_debug(level, ...) \
- do { \
- if (debug >= (level)) \
- pr_debug(__VA_ARGS__); \
- } while (0)
- /*
- * Check whether we have multi-touch enabled kernel; if not, report just the
- * first touch (on mXT224, the maximum is 10 simultaneous touches).
- * Because just the 1st one is reported, it might seem that the screen is not
- * responding to touch if the first touch is removed while the screen is being
- * touched by another finger, so beware.
- *
- */
- #ifdef ABS_MT_TRACKING_ID
- static inline void report_mt(int touch_number, int size, int x, int y, struct
- mxt_data *mxt) {
- input_report_abs(mxt->input, ABS_MT_TRACKING_ID, touch_number);
- input_report_abs(mxt->input, ABS_MT_TOUCH_MAJOR, size);
- input_report_abs(mxt->input, ABS_MT_POSITION_X, x);
- input_report_abs(mxt->input, ABS_MT_POSITION_Y, y);
- input_mt_sync(mxt->input);
- }
- #else
- static inline void report_mt(int touch_number, int size, int x, int y, struct
- mxt_data *mxt) {
- if (touch_number == 0) {
- input_report_abs(mxt->input, ABS_TOOL_WIDTH, size);
- input_report_abs(mxt->input, ABS_X, x);
- input_report_abs(mxt->input, ABS_Y, y);
- }
- }
- #endif
- static inline void report_gesture(int data, struct mxt_data *mxt)
- {
- input_event(mxt->input, EV_MSC, MSC_GESTURE, data);
- }
- static const u8 *object_type_name[] = {
- [0] = "Reserved",
- [5] = "GEN_MESSAGEPROCESSOR_T5",
- [6] = "GEN_COMMANDPROCESSOR_T6",
- [7] = "GEN_POWERCONFIG_T7",
- [8] = "GEN_ACQUIRECONFIG_T8",
- [9] = "TOUCH_MULTITOUCHSCREEN_T9",
- [15] = "TOUCH_KEYARRAY_T15",
- [17] = "SPT_COMMSCONFIG_T18",
- [19] = "SPT_GPIOPWM_T19",
- [20] = "PROCI_GRIPFACESUPPRESSION_T20",
- [22] = "PROCG_NOISESUPPRESSION_T22",
- [23] = "TOUCH_PROXIMITY_T23",
- [24] = "PROCI_ONETOUCHGESTUREPROCESSOR_T24",
- [25] = "SPT_SELFTEST_T25",
- [27] = "PROCI_TWOTOUCHGESTUREPROCESSOR_T27",
- [28] = "SPT_CTECONFIG_T28",
- [37] = "DEBUG_DIAGNOSTICS_T37",
- [38] = "SPT_USER_DATA_T38",
- [40] = "PROCI_GRIPSUPPRESSION_T40",
- [41] = "PROCI_PALMSUPPRESSION_T41",
- [42] = "PROCI_FACESUPPRESSION_T42",
- [43] = "SPT_DIGITIZER_T43",
- [44] = "SPT_MESSAGECOUNT_T44",
- };
- static u16 get_object_address(uint8_t object_type,
- uint8_t instance,
- struct mxt_object *object_table,
- int max_objs);
- int mxt_write_ap(struct mxt_data *mxt, u16 ap);
- static int mxt_read_block_wo_addr(struct i2c_client *client,
- u16 length,
- u8 *value);
- ssize_t debug_data_read(struct mxt_data *mxt, char *buf, size_t count,
- loff_t *ppos, u8 debug_command){
- int i;
- u16 *data;
- u16 diagnostics_reg;
- int offset = 0;
- int size;
- int read_size;
- int error;
- char *buf_start;
- u16 debug_data_addr;
- u16 page_address;
- u8 page;
- u8 debug_command_reg;
- data = mxt->debug_data;
- if (data == NULL)
- return -EIO;
- /* If first read after open, read all data to buffer. */
- if (mxt->current_debug_datap == 0){
- diagnostics_reg = MXT_BASE_ADDR(MXT_GEN_COMMANDPROCESSOR_T6,
- mxt) +
- MXT_ADR_T6_DIAGNOSTIC;
- if (count > (mxt->device_info.num_nodes * 2))
- count = mxt->device_info.num_nodes;
-
- debug_data_addr = MXT_BASE_ADDR(MXT_DEBUG_DIAGNOSTIC_T37, mxt)+
- MXT_ADR_T37_DATA;
- page_address = MXT_BASE_ADDR(MXT_DEBUG_DIAGNOSTIC_T37, mxt) +
- MXT_ADR_T37_PAGE;
- error = mxt_read_block(mxt->client, page_address, 1, &page);
- if (error < 0)
- return error;
- mxt_debug(DEBUG_TRACE, "debug data page = %d\n", page);
- while (page != 0) {
- error = mxt_write_byte(mxt->client,
- diagnostics_reg,
- MXT_CMD_T6_PAGE_DOWN);
- if (error < 0)
- return error;
- /* Wait for command to be handled; when it has, the
- register will be cleared. */
- debug_command_reg = 1;
- while (debug_command_reg != 0) {
- error = mxt_read_block(mxt->client,
- diagnostics_reg, 1,
- &debug_command_reg);
- if (error < 0)
- return error;
- mxt_debug(DEBUG_TRACE,
- "Waiting for debug diag command "
- "to propagate...\n");
- }
- error = mxt_read_block(mxt->client, page_address, 1,
- &page);
- if (error < 0)
- return error;
- mxt_debug(DEBUG_TRACE, "debug data page = %d\n", page);
- }
- /*
- * Lock mutex to prevent writing some unwanted data to debug
- * command register. User can still write through the char
- * device interface though. TODO: fix?
- */
- mutex_lock(&mxt->debug_mutex);
- /* Configure Debug Diagnostics object to show deltas/refs */
- error = mxt_write_byte(mxt->client, diagnostics_reg,
- debug_command);
- /* Wait for command to be handled; when it has, the
- * register will be cleared. */
- debug_command_reg = 1;
- while (debug_command_reg != 0) {
- error = mxt_read_block(mxt->client,
- diagnostics_reg, 1,
- &debug_command_reg);
- if (error < 0)
- return error;
- mxt_debug(DEBUG_TRACE, "Waiting for debug diag command "
- "to propagate...\n");
- }
- if (error < 0) {
- printk (KERN_WARNING
- "Error writing to maXTouch device!\n");
- return error;
- }
-
- size = mxt->device_info.num_nodes * sizeof(u16);
- while (size > 0) {
- read_size = size > 128 ? 128 : size;
- mxt_debug(DEBUG_TRACE,
- "Debug data read loop, reading %d bytes...\n",
- read_size);
- error = mxt_read_block(mxt->client,
- debug_data_addr,
- read_size,
- (u8 *) &data[offset]);
- if (error < 0) {
- printk(KERN_WARNING
- "Error reading debug data\n");
- goto error;
- }
- offset += read_size/2;
- size -= read_size;
- /* Select next page */
- error = mxt_write_byte(mxt->client, diagnostics_reg,
- MXT_CMD_T6_PAGE_UP);
- if (error < 0) {
- printk(KERN_WARNING
- "Error writing to maXTouch device!\n");
- goto error;
- }
- }
- mutex_unlock(&mxt->debug_mutex);
- }
- buf_start = buf;
- i = mxt->current_debug_datap;
- while (((buf- buf_start) < (count - 6)) &&
- (i < mxt->device_info.num_nodes)){
- mxt->current_debug_datap++;
- if (debug_command == MXT_CMD_T6_REFERENCES_MODE)
- buf += sprintf(buf, "%d: %5d\n", i,
- (u16) le16_to_cpu(data[i]));
- else if (debug_command == MXT_CMD_T6_DELTAS_MODE)
- buf += sprintf(buf, "%d: %5d\n", i,
- (s16) le16_to_cpu(data[i]));
- i++;
- }
- return (buf - buf_start);
- error:
- mutex_unlock(&mxt->debug_mutex);
- return error;
- }
- ssize_t deltas_read(struct file *file, char *buf, size_t count, loff_t *ppos)
- {
- return debug_data_read(file->private_data, buf, count, ppos,
- MXT_CMD_T6_DELTAS_MODE);
- }
- ssize_t refs_read(struct file *file, char *buf, size_t count,
- loff_t *ppos)
- {
- return debug_data_read(file->private_data, buf, count, ppos,
- MXT_CMD_T6_REFERENCES_MODE);
- }
- int debug_data_open(struct inode *inode, struct file *file)
- {
- struct mxt_data *mxt;
- int i;
- mxt = inode->i_private;
- if (mxt == NULL)
- return -EIO;
- mxt->current_debug_datap = 0;
- mxt->debug_data = kmalloc(mxt->device_info.num_nodes * sizeof(u16),
- GFP_KERNEL);
- if (mxt->debug_data == NULL)
- return -ENOMEM;
-
- for (i = 0; i < mxt->device_info.num_nodes; i++)
- mxt->debug_data[i] = 7777;
-
- file->private_data = mxt;
- return 0;
- }
- int debug_data_release(struct inode *inode, struct file *file)
- {
- struct mxt_data *mxt;
- mxt = file->private_data;
- kfree(mxt->debug_data);
- return 0;
- }
- static struct file_operations delta_fops = {
- .owner = THIS_MODULE,
- .open = debug_data_open,
- .release = debug_data_release,
- .read = deltas_read,
- };
- static struct file_operations refs_fops = {
- .owner = THIS_MODULE,
- .open = debug_data_open,
- .release = debug_data_release,
- .read = refs_read,
- };
- int mxt_memory_open(struct inode *inode, struct file *file)
- {
- struct mxt_data *mxt;
- mxt = container_of(inode->i_cdev, struct mxt_data, cdev);
- if (mxt == NULL)
- return -EIO;
- file->private_data = mxt;
- return 0;
- }
- int mxt_message_open(struct inode *inode, struct file *file)
- {
- struct mxt_data *mxt;
- mxt = container_of(inode->i_cdev, struct mxt_data, cdev_messages);
- if (mxt == NULL)
- return -EIO;
- file->private_data = mxt;
- return 0;
- }
- ssize_t mxt_memory_read(struct file *file, char *buf, size_t count,
- loff_t *ppos)
- {
- int i;
- struct mxt_data *mxt;
- mxt = file->private_data;
- if (mxt->valid_ap){
- mxt_debug(DEBUG_TRACE, "Reading %d bytes from current ap\n",
- (int) count);
- i = mxt_read_block_wo_addr(mxt->client, count, (u8 *) buf);
- } else {
- mxt_debug(DEBUG_TRACE, "Address pointer changed since set;"
- "writing AP (%d) before reading %d bytes",
- mxt->address_pointer, (int) count);
- i = mxt_read_block(mxt->client, mxt->address_pointer, count,
- buf);
- }
-
- return i;
- }
- ssize_t mxt_memory_write(struct file *file, const char *buf, size_t count,
- loff_t *ppos)
- {
- int i;
- int whole_blocks;
- int last_block_size;
- struct mxt_data *mxt;
- u16 address;
-
- mxt = file->private_data;
- address = mxt->address_pointer;
- mxt_debug(DEBUG_TRACE, "mxt_memory_write entered\n");
- whole_blocks = count / I2C_PAYLOAD_SIZE;
- last_block_size = count % I2C_PAYLOAD_SIZE;
- for (i = 0; i < whole_blocks; i++) {
- mxt_debug(DEBUG_TRACE, "About to write to %d...",
- address);
- mxt_write_block(mxt->client, address, I2C_PAYLOAD_SIZE,
- (u8 *) buf);
- address += I2C_PAYLOAD_SIZE;
- buf += I2C_PAYLOAD_SIZE;
- }
- mxt_write_block(mxt->client, address, last_block_size, (u8 *) buf);
- return count;
- }
- static long mxt_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
- {
- int retval;
- struct mxt_data *mxt;
- retval = 0;
- mxt = file->private_data;
- switch (cmd) {
- case MXT_SET_ADDRESS_IOCTL:
- retval = mxt_write_ap(mxt, (u16) arg);
- if (retval >= 0) {
- mxt->address_pointer = (u16) arg;
- mxt->valid_ap = 1;
- }
- break;
- case MXT_RESET_IOCTL:
- retval = mxt_write_byte(mxt->client,
- MXT_BASE_ADDR(MXT_GEN_COMMANDPROCESSOR_T6, mxt) +
- MXT_ADR_T6_RESET,
- 1);
- break;
- case MXT_CALIBRATE_IOCTL:
- retval = mxt_write_byte(mxt->client,
- MXT_BASE_ADDR(MXT_GEN_COMMANDPROCESSOR_T6, mxt) +
- MXT_ADR_T6_CALIBRATE,
- 1);
- break;
- case MXT_BACKUP_IOCTL:
- retval = mxt_write_byte(mxt->client,
- MXT_BASE_ADDR(MXT_GEN_COMMANDPROCESSOR_T6, mxt) +
- MXT_ADR_T6_BACKUPNV,
- MXT_CMD_T6_BACKUP);
- break;
- case MXT_NONTOUCH_MSG_IOCTL:
- mxt->nontouch_msg_only = 1;
- break;
- case MXT_ALL_MSG_IOCTL:
- mxt->nontouch_msg_only = 0;
- break;
- default:
- return -EIO;
- }
- return retval;
- }
- /*
- * Copies messages from buffer to user space.
- *
- * NOTE: if less than (mxt->message_size * 5 + 1) bytes requested,
- * this will return 0!
- *
- */
- ssize_t mxt_message_read(struct file *file, char *buf, size_t count,
- loff_t *ppos)
- {
- int i;
- struct mxt_data *mxt;
- char *buf_start;
-
- mxt = file->private_data;
- if (mxt == NULL)
- return -EIO;
- buf_start = buf;
- mutex_lock(&mxt->msg_mutex);
- /* Copy messages until buffer empty, or 'count' bytes written */
- while ((mxt->msg_buffer_startp != mxt->msg_buffer_endp) &&
- ((buf - buf_start) < (count - (5 * mxt->message_size) - 1))){
- for (i = 0; i < mxt->message_size; i++){
- buf += sprintf(buf, "[%2X] ",
- *(mxt->messages + mxt->msg_buffer_endp *
- mxt->message_size + i));
- }
- buf += sprintf(buf, "\n");
- if (mxt->msg_buffer_endp < MXT_MESSAGE_BUFFER_SIZE)
- mxt->msg_buffer_endp++;
- else
- mxt->msg_buffer_endp = 0;
- }
- mutex_unlock(&mxt->msg_mutex);
- return (buf - buf_start);
- }
- static struct file_operations mxt_message_fops = {
- .owner = THIS_MODULE,
- .open = mxt_message_open,
- .read = mxt_message_read,
- };
- static struct file_operations mxt_memory_fops = {
- .owner = THIS_MODULE,
- .open = mxt_memory_open,
- .read = mxt_memory_read,
- .write = mxt_memory_write,
- .unlocked_ioctl = mxt_ioctl,
- };
- /* Writes the address pointer (to set up following reads). */
- int mxt_write_ap(struct mxt_data *mxt, u16 ap)
- {
- struct i2c_client *client;
- __le16 le_ap = cpu_to_le16(ap);
- client = mxt->client;
- if (mxt != NULL)
- mxt->last_read_addr = -1;
- if (i2c_master_send(client, (u8 *) &le_ap, 2) == 2) {
- mxt_debug(DEBUG_TRACE, "Address pointer set to %d\n", ap);
- return 0;
- } else {
- mxt_debug(DEBUG_INFO, "Error writing address pointer!\n");
- return -EIO;
- }
- }
- /* Calculates the 24-bit CRC sum. */
- static u32 CRC_24(u32 crc, u8 byte1, u8 byte2)
- {
- static const u32 crcpoly = 0x80001B;
- u32 result;
- u32 data_word;
- data_word = ((((u16) byte2) << 8u) | byte1);
- result = ((crc << 1u) ^ data_word);
- if (result & 0x1000000)
- result ^= crcpoly;
- return result;
- }
- /* Returns object address in mXT chip, or zero if object is not found */
- static u16 get_object_address(uint8_t object_type,
- uint8_t instance,
- struct mxt_object *object_table,
- int max_objs)
- {
- uint8_t object_table_index = 0;
- uint8_t address_found = 0;
- uint16_t address = 0;
- struct mxt_object *obj;
- while ((object_table_index < max_objs) && !address_found) {
- obj = &object_table[object_table_index];
- if (obj->type == object_type) {
- address_found = 1;
- /* Are there enough instances defined in the FW? */
- if (obj->instances >= instance) {
- address = obj->chip_addr +
- (obj->size + 1) * instance;
- } else {
- return 0;
- }
- }
- object_table_index++;
- }
- return address;
- }
- /*
- * Reads a block of bytes from given address from mXT chip. If we are
- * reading from message window, and previous read was from message window,
- * there's no need to write the address pointer: the mXT chip will
- * automatically set the address pointer back to message window start.
- */
- static int mxt_read_block(struct i2c_client *client,
- u16 addr,
- u16 length,
- u8 *value)
- {
- struct i2c_adapter *adapter = client->adapter;
- struct i2c_msg msg[2];
- __le16 le_addr;
- struct mxt_data *mxt;
- mxt = i2c_get_clientdata(client);
- if (mxt != NULL) {
- if ((mxt->last_read_addr == addr) &&
- (addr == mxt->msg_proc_addr)) {
- if (i2c_master_recv(client, value, length) == length)
- return length;
- else
- return -EIO;
- } else {
- mxt->last_read_addr = addr;
- }
- }
- mxt_debug(DEBUG_TRACE, "Writing address pointer & reading %d bytes "
- "in on i2c transaction...\n", length);
- le_addr = cpu_to_le16(addr);
- msg[0].addr = client->addr;
- msg[0].flags = 0x00;
- msg[0].len = 2;
- msg[0].buf = (u8 *) &le_addr;
- msg[1].addr = client->addr;
- msg[1].flags = I2C_M_RD;
- msg[1].len = length;
- msg[1].buf = (u8 *) value;
- if (i2c_transfer(adapter, msg, 2) == 2)
- return length;
- else
- return -EIO;
- }
- /* Reads a block of bytes from current address from mXT chip. */
- static int mxt_read_block_wo_addr(struct i2c_client *client,
- u16 length,
- u8 *value)
- {
- if (i2c_master_recv(client, value, length) == length) {
- mxt_debug(DEBUG_TRACE, "I2C block read ok\n");
- return length;
- } else {
- mxt_debug(DEBUG_INFO, "I2C block read failed\n");
- return -EIO;
- }
- }
- /* Writes one byte to given address in mXT chip. */
- static int mxt_write_byte(struct i2c_client *client, u16 addr, u8 value)
- {
- struct {
- __le16 le_addr;
- u8 data;
- } i2c_byte_transfer;
- struct mxt_data *mxt;
- mxt = i2c_get_clientdata(client);
- if (mxt != NULL)
- mxt->last_read_addr = -1;
- i2c_byte_transfer.le_addr = cpu_to_le16(addr);
- i2c_byte_transfer.data = value;
- if (i2c_master_send(client, (u8 *) &i2c_byte_transfer, 3) == 3)
- return 0;
- else
- return -EIO;
- }
- /* Writes a block of bytes (max 256) to given address in mXT chip. */
- static int mxt_write_block(struct i2c_client *client,
- u16 addr,
- u16 length,
- u8 *value)
- {
- int i;
- struct {
- __le16 le_addr;
- u8 data[256];
- } i2c_block_transfer;
- struct mxt_data *mxt;
- mxt_debug(DEBUG_TRACE, "Writing %d bytes to %d...", length, addr);
- if (length > 256)
- return -EINVAL;
- mxt = i2c_get_clientdata(client);
- if (mxt != NULL)
- mxt->last_read_addr = -1;
- for (i = 0; i < length; i++)
- i2c_block_transfer.data[i] = *value++;
- i2c_block_transfer.le_addr = cpu_to_le16(addr);
- i = i2c_master_send(client, (u8 *) &i2c_block_transfer, length + 2);
- if (i == (length + 2))
- return length;
- else
- return -EIO;
- }
- /* Calculates the CRC value for mXT infoblock. */
- int calculate_infoblock_crc(u32 *crc_result, u8 *data, int crc_area_size)
- {
- u32 crc = 0;
- int i;
- for (i = 0; i < (crc_area_size - 1); i = i + 2)
- crc = CRC_24(crc, *(data + i), *(data + i + 1));
- /* If uneven size, pad with zero */
- if (crc_area_size & 0x0001)
- crc = CRC_24(crc, *(data + i), 0);
- /* Return only 24 bits of CRC. */
- *crc_result = (crc & 0x00FFFFFF);
- return 0;
- }
- /* Processes a touchscreen message. */
- void process_T9_message(u8 *message, struct mxt_data *mxt, int last_touch)
- {
- struct input_dev *input;
- u8 status;
- u16 xpos = 0xFFFF;
- u16 ypos = 0xFFFF;
- u8 touch_size = 255;
- u8 touch_number;
- u8 amplitude;
- u8 report_id;
- static int stored_size[10];
- static int stored_x[10];
- static int stored_y[10];
- int i;
- int active_touches = 0;
- /*
- * If the 'last_touch' flag is set, we have received all the touch
- * messages
- * there are available in this cycle, so send the events for touches
- * that are
- * active.
- */
- if (last_touch){
- /* TODO: For compatibility with single-touch systems, send ABS_X &
- * ABS_Y */
- /*
- if (stored_size[0]){
- input_report_abs(mxt->input, ABS_X, stored_x[0]);
- input_report_abs(mxt->input, ABS_Y, stored_y[0]);
- }*/
-
- for (i = 0; i < 10; i++){
- if (stored_size[i]){
- active_touches++;
- input_report_abs(mxt->input,
- ABS_MT_TRACKING_ID,
- i);
- input_report_abs(mxt->input,
- ABS_MT_TOUCH_MAJOR,
- stored_size[i]);
- input_report_abs(mxt->input,
- ABS_MT_POSITION_X,
- stored_x[i]);
- input_report_abs(mxt->input,
- ABS_MT_POSITION_Y,
- stored_y[i]);
- input_mt_sync(mxt->input);
- }
- }
- input_report_key(mxt->input, BTN_TOUCH, !!active_touches);
- if (active_touches == 0)
- input_mt_sync(mxt->input);
- input_sync(mxt->input);
-
- }else{
- input = mxt->input;
- status = message[MXT_MSG_T9_STATUS];
- report_id = message[0];
- if (status & MXT_MSGB_T9_SUPPRESS) {
- /* Touch has been suppressed by grip/face */
- /* detection */
- mxt_debug(DEBUG_TRACE, "SUPRESS");
- } else {
- /* Put together the 10-/12-bit coordinate values. */
- xpos = message[MXT_MSG_T9_XPOSMSB] * 16 +
- ((message[MXT_MSG_T9_XYPOSLSB] >> 4) & 0xF);
- ypos = message[MXT_MSG_T9_YPOSMSB] * 16 +
- ((message[MXT_MSG_T9_XYPOSLSB] >> 0) & 0xF);
- if (mxt->max_x_val < 1024)
- xpos >>= 2;
- if (mxt->max_y_val < 1024)
- ypos >>= 2;
- touch_number = message[MXT_MSG_REPORTID] -
- mxt->rid_map[report_id].first_rid;
- stored_x[touch_number] = xpos;
- stored_y[touch_number] = ypos;
- if (status & MXT_MSGB_T9_DETECT) {
- /*
- * mXT224 reports the number of touched nodes,
- * so the exact value for touch ellipse major
- * axis length in nodes would be 2*sqrt(touch_size/pi)
- * (assuming round touch shape), which would then need
- * to be scaled using information about how many sensor
- * lines we do have. So this is very much simplified,
- * but sufficient for most if not all apps?
- */
- touch_size = message[MXT_MSG_T9_TCHAREA];
- touch_size = touch_size >> 2;
- if (!touch_size)
- touch_size = 1;
- /*
- * report_mt(touch_number, touch_size, xpos, ypos, mxt);
- */
- stored_size[touch_number] = touch_size;
- if (status & MXT_MSGB_T9_AMP)
- /* Amplitude of touch has changed */
- amplitude = message[MXT_MSG_T9_TCHAMPLITUDE];
- }
- if (status & MXT_MSGB_T9_RELEASE) {
- /* The previously reported touch has been removed.*/
- /* report_mt(touch_number, 0, xpos, ypos, mxt); */
- stored_size[touch_number] = 0;
- }
- /* input_sync(input); */
- }
-
- if (status & MXT_MSGB_T9_SUPPRESS) {
- mxt_debug(DEBUG_TRACE, "SUPRESS");
- } else {
- if (status & MXT_MSGB_T9_DETECT) {
- mxt_debug(DEBUG_TRACE, "DETECT:%s%s%s%s",
- ((status & MXT_MSGB_T9_PRESS) ? " PRESS" : ""),
- ((status & MXT_MSGB_T9_MOVE) ? " MOVE" : ""),
- ((status & MXT_MSGB_T9_AMP) ? " AMP" : ""),
- ((status & MXT_MSGB_T9_VECTOR) ? " VECT" : ""));
- } else if (status & MXT_MSGB_T9_RELEASE) {
- mxt_debug(DEBUG_TRACE, "RELEASE");
- }
- }
- mxt_debug(DEBUG_TRACE, "X=%d, Y=%d, TOUCHSIZE=%d",
- xpos, ypos, touch_size);
- }
- return;
- }
- int process_message(u8 *message, u8 object, struct mxt_data *mxt)
- {
- struct i2c_client *client;
- u8 status;
- u16 xpos = 0xFFFF;
- u16 ypos = 0xFFFF;
- u8 event;
- u8 direction;
- u16 distance;
- u8 length;
- u8 report_id;
- static u8 error_cond = 0;
- client = mxt->client;
- length = mxt->message_size;
- report_id = message[0];
- if ((mxt->nontouch_msg_only == 0) ||
- (!IS_TOUCH_OBJECT(object))){
- mutex_lock(&mxt->msg_mutex);
- /* Copy the message to buffer */
- if (mxt->msg_buffer_startp < MXT_MESSAGE_BUFFER_SIZE) {
- mxt->msg_buffer_startp++;
- } else {
- mxt->msg_buffer_startp = 0;
- }
-
- if (mxt->msg_buffer_startp == mxt->msg_buffer_endp) {
- mxt_debug(DEBUG_TRACE,
- "Message buf full, discarding last entry.\n");
- if (mxt->msg_buffer_endp < MXT_MESSAGE_BUFFER_SIZE) {
- mxt->msg_buffer_endp++;
- } else {
- mxt->msg_buffer_endp = 0;
- }
- }
- memcpy((mxt->messages + mxt->msg_buffer_startp * length),
- message,
- length);
- mutex_unlock(&mxt->msg_mutex);
- }
- switch (object) {
- case MXT_GEN_COMMANDPROCESSOR_T6:
- status = message[1];
- if (status & MXT_MSGB_T6_COMSERR) {
- if ((!error_cond) & MXT_MSGB_T6_COMSERR){
- dev_err(&client->dev,
- "maXTouch checksum error\n");
- error_cond |= MXT_MSGB_T6_COMSERR;
- }
- }
- if (status & MXT_MSGB_T6_CFGERR) {
- /*
- * Configuration error. A proper configuration
- * needs to be written to chip and backed up.
- */
- if ((!error_cond) & MXT_MSGB_T6_CFGERR){
- dev_err(&client->dev,
- "maXTouch configuration error\n");
- error_cond |= MXT_MSGB_T6_CFGERR;
- }
- }
- if (status & MXT_MSGB_T6_CAL) {
- /* Calibration in action, no need to react */
- dev_dbg(&client->dev,
- "maXTouch calibration in progress\n");
- }
- if (status & MXT_MSGB_T6_SIGERR) {
- /*
- * Signal acquisition error, something is seriously
- * wrong, not much we can in the driver to correct
- * this
- */
- if ((!error_cond) & MXT_MSGB_T6_SIGERR){
- dev_err(&client->dev,
- "maXTouch acquisition error\n");
- error_cond |= MXT_MSGB_T6_SIGERR;
- }
- }
- if (status & MXT_MSGB_T6_OFL) {
- /*
- * Cycle overflow, the acquisition interval is too
- * short.
- */
- dev_err(&client->dev,
- "maXTouch cycle overflow\n");
- }
- if (status & MXT_MSGB_T6_RESET) {
- /* Chip has reseted, no need to react. */
- dev_dbg(&client->dev,
- "maXTouch chip reset\n");
- }
- if (status == 0) {
- /* Chip status back to normal. */
- dev_dbg(&client->dev,
- "maXTouch status normal\n");
- error_cond = 0;
- }
- break;
- case MXT_TOUCH_MULTITOUCHSCREEN_T9:
- process_T9_message(message, mxt, 0);
- break;
- case MXT_SPT_GPIOPWM_T19:
- if (debug >= DEBUG_TRACE)
- dev_info(&client->dev,
- "Receiving GPIO message\n");
- break;
- case MXT_PROCI_GRIPFACESUPPRESSION_T20:
- if (debug >= DEBUG_TRACE)
- dev_info(&client->dev,
- "Receiving face suppression msg\n");
- break;
- case MXT_PROCG_NOISESUPPRESSION_T22:
- if (debug >= DEBUG_TRACE)
- dev_info(&client->dev,
- "Receiving noise suppression msg\n");
- status = message[MXT_MSG_T22_STATUS];
- if (status & MXT_MSGB_T22_FHCHG) {
- if (debug >= DEBUG_TRACE)
- dev_info(&client->dev,
- "maXTouch: Freq changed\n");
- }
- if (status & MXT_MSGB_T22_GCAFERR) {
- if (debug >= DEBUG_TRACE)
- dev_info(&client->dev,
- "maXTouch: High noise "
- "level\n");
- }
- if (status & MXT_MSGB_T22_FHERR) {
- if (debug >= DEBUG_TRACE)
- dev_info(&client->dev,
- "maXTouch: Freq changed - "
- "Noise level too high\n");
- }
- break;
- case MXT_PROCI_ONETOUCHGESTUREPROCESSOR_T24:
- if (debug >= DEBUG_TRACE)
- dev_info(&client->dev,
- "Receiving one-touch gesture msg\n");
- event = message[MXT_MSG_T24_STATUS] & 0x0F;
- xpos = message[MXT_MSG_T24_XPOSMSB] * 16 +
- ((message[MXT_MSG_T24_XYPOSLSB] >> 4) & 0x0F);
- ypos = message[MXT_MSG_T24_YPOSMSB] * 16 +
- ((message[MXT_MSG_T24_XYPOSLSB] >> 0) & 0x0F);
- if (mxt->max_x_val < 1024)
- xpos >>= 2;
- if (mxt->max_y_val < 1024)
- ypos >>= 2;
- direction = message[MXT_MSG_T24_DIR];
- distance = message[MXT_MSG_T24_DIST] +
- (message[MXT_MSG_T24_DIST + 1] << 16);
- report_gesture((event << 24) | (direction << 16) | distance,
- mxt);
- report_gesture((xpos << 16) | ypos, mxt);
- break;
- case MXT_SPT_SELFTEST_T25:
- if (debug >= DEBUG_TRACE)
- dev_info(&client->dev,
- "Receiving Self-Test msg\n");
- if (message[MXT_MSG_T25_STATUS] == MXT_MSGR_T25_OK) {
- if (debug >= DEBUG_TRACE)
- dev_info(&client->dev,
- "maXTouch: Self-Test OK\n");
- } else {
- dev_err(&client->dev,
- "maXTouch: Self-Test Failed [%02x]:"
- "{%02x,%02x,%02x,%02x,%02x}\n",
- message[MXT_MSG_T25_STATUS],
- message[MXT_MSG_T25_STATUS + 0],
- message[MXT_MSG_T25_STATUS + 1],
- message[MXT_MSG_T25_STATUS + 2],
- message[MXT_MSG_T25_STATUS + 3],
- message[MXT_MSG_T25_STATUS + 4]
- );
- }
- break;
- case MXT_PROCI_TWOTOUCHGESTUREPROCESSOR_T27:
- if (debug >= DEBUG_TRACE)
- dev_info(&client->dev,
- "Receiving 2-touch gesture message\n");
- event = message[MXT_MSG_T27_STATUS] & 0xF0;
- xpos = message[MXT_MSG_T27_XPOSMSB] * 16 +
- ((message[MXT_MSG_T27_XYPOSLSB] >> 4) & 0x0F);
- ypos = message[MXT_MSG_T27_YPOSMSB] * 16 +
- ((message[MXT_MSG_T27_XYPOSLSB] >> 0) & 0x0F);
- if (mxt->max_x_val < 1024)
- xpos >>= 2;
- if (mxt->max_y_val < 1024)
- ypos >>= 2;
- direction = message[MXT_MSG_T27_ANGLE];
- distance = message[MXT_MSG_T27_SEPARATION] +
- (message[MXT_MSG_T27_SEPARATION + 1] << 16);
- report_gesture((event << 24) | (direction << 16) | distance,
- mxt);
- report_gesture((xpos << 16) | ypos, mxt);
- break;
- case MXT_SPT_CTECONFIG_T28:
- if (debug >= DEBUG_TRACE)
- dev_info(&client->dev,
- "Receiving CTE message...\n");
- status = message[MXT_MSG_T28_STATUS];
- if (status & MXT_MSGB_T28_CHKERR)
- dev_err(&client->dev,
- "maXTouch: Power-Up CRC failure\n");
- break;
- default:
- if (debug >= DEBUG_TRACE)
- dev_info(&client->dev,
- "maXTouch: Unknown message!\n");
- break;
- }
- return 0;
- }
- /*
- * Processes messages when the interrupt line (CHG) is asserted. Keeps
- * reading messages until a message with report ID 0xFF is received,
- * which indicates that there is no more new messages.
- *
- */
- static void mxt_worker(struct work_struct *work)
- {
- struct mxt_data *mxt;
- struct i2c_client *client;
- u8 *message;
- u16 message_length;
- u16 message_addr;
- u8 report_id;
- u8 object;
- int error;
- int i;
- char *message_string;
- char *message_start;
- message = NULL;
- mxt = container_of(work, struct mxt_data, dwork.work);
- client = mxt->client;
- message_addr = mxt->msg_proc_addr;
- message_length = mxt->message_size;
- if (message_length < 256) {
- message = kmalloc(message_length, GFP_KERNEL);
- if (message == NULL) {
- dev_err(&client->dev, "Error allocating memory\n");
- goto fail_worker;
- }
- } else {
- dev_err(&client->dev,
- "Message length larger than 256 bytes not supported\n");
- goto fail_worker;
- }
- mxt_debug(DEBUG_TRACE, "maXTouch worker active:\n");
-
- do {
- /* Read next message, reread on failure. */
- /* TODO: message length, CRC included? */
- mxt->message_counter++;
- for (i = 1; i < I2C_RETRY_COUNT; i++) {
- error = mxt_read_block(client,
- message_addr,
- message_length - 1,
- message);
- if (error >= 0)
- break;
- mxt->read_fail_counter++;
- dev_err(&client->dev,
- "Failure reading maxTouch device\n");
- }
- if (error < 0) {
- kfree(message);
- goto fail_worker;
- }
-
- if (mxt->address_pointer != message_addr)
- mxt->valid_ap = 0;
- report_id = message[0];
- if (debug >= DEBUG_RAW) {
- mxt_debug(DEBUG_RAW, "%s message [msg count: %08x]:",
- REPORT_ID_TO_OBJECT_NAME(report_id, mxt),
- mxt->message_counter
- );
- /* 5 characters per one byte */
- message_string = kmalloc(message_length * 5,
- GFP_KERNEL);
- if (message_string == NULL) {
- dev_err(&client->dev,
- "Error allocating memory\n");
- kfree(message);
- goto fail_worker;
- }
- message_start = message_string;
- for (i = 0; i < message_length; i++) {
- message_string +=
- sprintf(message_string,
- "0x%02X ", message[i]);
- }
- mxt_debug(DEBUG_RAW, "%s", message_start);
- kfree(message_start);
- }
-
- if ((report_id != MXT_END_OF_MESSAGES) && (report_id != 0)) {
- memcpy(mxt->last_message, message, message_length);
- mxt->new_msgs = 1;
- smp_wmb();
- /* Get type of object and process the message */
- object = mxt->rid_map[report_id].object;
- process_message(message, object, mxt);
- }
- mxt_debug(DEBUG_TRACE, "chgline: %d\n", mxt->read_chg());
- } while (comms ? (mxt->read_chg() == 0) :
- ((report_id != MXT_END_OF_MESSAGES) && (report_id != 0)));
- /* All messages processed, send the events) */
- process_T9_message(NULL, mxt, 1);
- kfree(message);
- fail_worker:
- /* Make sure we just didn't miss a interrupt. */
- if (mxt->read_chg() == 0){
- schedule_delayed_work(&mxt->dwork, 0);
- } else
- enable_irq(mxt->irq);
- }
- /*
- * The maXTouch device will signal the host about a new message by asserting
- * the CHG line. This ISR schedules a worker routine to read the message when
- * that happens.
- */
- static irqreturn_t mxt_irq_handler(int irq, void *_mxt)
- {
- struct mxt_data *mxt = _mxt;
- mxt->irq_counter++;
- if (mxt->valid_interrupt()) {
- /* Send the signal only if falling edge generated the irq. */
- disable_irq_nosync(mxt->irq);
- schedule_delayed_work(&mxt->dwork, 0);
- mxt->valid_irq_counter++;
- } else {
- mxt->invalid_irq_counter++;
- return IRQ_NONE;
- }
- return IRQ_HANDLED;
- }
- /******************************************************************************/
- /* Initialization of driver */
- /******************************************************************************/
- static int __devinit mxt_identify(struct i2c_client *client,
- struct mxt_data *mxt,
- u8 *id_block_data)
- {
- u8 buf[MXT_ID_BLOCK_SIZE];
- int error;
- int identified;
- identified = 0;
- /* Read Device info to check if chip is valid */
- error = mxt_read_block(client, MXT_ADDR_INFO_BLOCK, MXT_ID_BLOCK_SIZE,
- (u8 *) buf);
- if (error < 0) {
- mxt->read_fail_counter++;
- dev_err(&client->dev, "Failure accessing maXTouch device\n");
- return -EIO;
- }
- memcpy(id_block_data, buf, MXT_ID_BLOCK_SIZE);
- mxt->device_info.family_id = buf[0];
- mxt->device_info.variant_id = buf[1];
- mxt->device_info.major = ((buf[2] >> 4) & 0x0F);
- mxt->device_info.minor = (buf[2] & 0x0F);
- mxt->device_info.build = buf[3];
- mxt->device_info.x_size = buf[4];
- mxt->device_info.y_size = buf[5];
- mxt->device_info.num_objs = buf[6];
- mxt->device_info.num_nodes = mxt->device_info.x_size *
- mxt->device_info.y_size;
- /*
- * Check Family & Variant Info; warn if not recognized but
- * still continue.
- */
- /* MXT224 */
- if (mxt->device_info.family_id == MXT224_FAMILYID) {
- strcpy(mxt->device_info.family_name, "mXT224");
- if (mxt->device_info.variant_id == MXT224_CAL_VARIANTID) {
- strcpy(mxt->device_info.variant_name, "Calibrated");
- } else if (mxt->device_info.variant_id ==
- MXT224_UNCAL_VARIANTID) {
- strcpy(mxt->device_info.variant_name, "Uncalibrated");
- } else {
- dev_err(&client->dev,
- "Warning: maXTouch Variant ID [%d] not "
- "supported\n",
- mxt->device_info.variant_id);
- strcpy(mxt->device_info.variant_name, "UNKNOWN");
- /* identified = -ENXIO; */
- }
- /* MXT1386 */
- } else if (mxt->device_info.family_id == MXT1386_FAMILYID) {
- strcpy(mxt->device_info.family_name, "mXT1386");
- if (mxt->device_info.variant_id == MXT1386_CAL_VARIANTID) {
- strcpy(mxt->device_info.variant_name, "Calibrated");
- } else {
- dev_err(&client->dev,
- "Warning: maXTouch Variant ID [%d] not "
- "supported\n",
- mxt->device_info.variant_id);
- strcpy(mxt->device_info.variant_name, "UNKNOWN");
- /* identified = -ENXIO; */
- }
- /* Unknown family ID! */
- } else {
- dev_err(&client->dev,
- "Warning: maXTouch Family ID [%d] not supported\n",
- mxt->device_info.family_id);
- strcpy(mxt->device_info.family_name, "UNKNOWN");
- strcpy(mxt->device_info.variant_name, "UNKNOWN");
- /* identified = -ENXIO; */
- }
- dev_info(
- &client->dev,
- "Atmel maXTouch (Family %s (%X), Variant %s (%X)) Firmware "
- "version [%d.%d] Build %d\n",
- mxt->device_info.family_name,
- mxt->device_info.family_id,
- mxt->device_info.variant_name,
- mxt->device_info.variant_id,
- mxt->device_info.major,
- mxt->device_info.minor,
- mxt->device_info.build
- );
- dev_dbg(
- &client->dev,
- "Atmel maXTouch Configuration "
- "[X: %d] x [Y: %d]\n",
- mxt->device_info.x_size,
- mxt->device_info.y_size
- );
- return identified;
- }
- /*
- * Reads the object table from maXTouch chip to get object data like
- * address, size, report id. For Info Block CRC calculation, already read
- * id data is passed to this function too (Info Block consists of the ID
- * block and object table).
- *
- */
- static int __devinit mxt_read_object_table(struct i2c_client *client,
- struct mxt_data *mxt,
- u8 *raw_id_data)
- {
- u16 report_id_count;
- u8 buf[MXT_OBJECT_TABLE_ELEMENT_SIZE];
- u8 *raw_ib_data;
- u8 object_type;
- u16 object_address;
- u16 object_size;
- u8 object_instances;
- u8 object_report_ids;
- u16 object_info_address;
- u32 crc;
- u32 calculated_crc;
- int i;
- int error;
- u8 object_instance;
- u8 object_report_id;
- u8 report_id;
- int first_report_id;
- int ib_pointer;
- struct mxt_object *object_table;
- mxt_debug(DEBUG_TRACE, "maXTouch driver reading configuration\n");
- object_table = kzalloc(sizeof(struct mxt_object) *
- mxt->device_info.num_objs,
- GFP_KERNEL);
- if (object_table == NULL) {
- printk(KERN_WARNING "maXTouch: Memory allocation failed!\n");
- error = -ENOMEM;
- goto err_object_table_alloc;
- }
- raw_ib_data = kmalloc(MXT_OBJECT_TABLE_ELEMENT_SIZE *
- mxt->device_info.num_objs + MXT_ID_BLOCK_SIZE,
- GFP_KERNEL);
- if (raw_ib_data == NULL) {
- printk(KERN_WARNING "maXTouch: Memory allocation failed!\n");
- error = -ENOMEM;
- goto err_ib_alloc;
- }
- /* Copy the ID data for CRC calculation. */
- memcpy(raw_ib_data, raw_id_data, MXT_ID_BLOCK_SIZE);
- ib_pointer = MXT_ID_BLOCK_SIZE;
- mxt->object_table = object_table;
- mxt_debug(DEBUG_TRACE, "maXTouch driver Memory allocated\n");
- object_info_address = MXT_ADDR_OBJECT_TABLE;
- report_id_count = 0;
- for (i = 0; i < mxt->device_info.num_objs; i++) {
- mxt_debug(DEBUG_TRACE, "Reading maXTouch at [0x%04x]: ",
- object_info_address);
- error = mxt_read_block(client, object_info_address,
- MXT_OBJECT_TABLE_ELEMENT_SIZE, buf);
- if (error < 0) {
- mxt->read_fail_counter++;
- dev_err(&client->dev,
- "maXTouch Object %d could not be read\n", i);
- error = -EIO;
- goto err_object_read;
- }
- memcpy(raw_ib_data + ib_pointer, buf,
- MXT_OBJECT_TABLE_ELEMENT_SIZE);
- ib_pointer += MXT_OBJECT_TABLE_ELEMENT_SIZE;
- object_type = buf[0];
- object_address = (buf[2] << 8) + buf[1];
- object_size = buf[3] + 1;
- object_instances = buf[4] + 1;
- object_report_ids = buf[5];
- mxt_debug(DEBUG_TRACE, "Type=%03d, Address=0x%04x, "
- "Size=0x%02x, %d instances, %d report id's\n",
- object_type,
- object_address,
- object_size,
- object_instances,
- object_report_ids
- );
- if (object_type == 38)
- t38_size = object_size;
- /* TODO: check whether object is known and supported? */
-
- /* Save frequently needed info. */
- if (object_type == MXT_GEN_MESSAGEPROCESSOR_T5) {
- mxt->msg_proc_addr = object_address;
- mxt->message_size = object_size;
- }
- object_table[i].type = object_type;
- object_table[i].chip_addr = object_address;
- object_table[i].size = object_size;
- object_table[i].instances = object_instances;
- object_table[i].num_report_ids = object_report_ids;
- report_id_count += object_instances * object_report_ids;
- object_info_address += MXT_OBJECT_TABLE_ELEMENT_SIZE;
- }
- mxt->rid_map =
- kzalloc(sizeof(struct report_id_map) * (report_id_count + 1),
- /* allocate for report_id 0, even if not used */
- GFP_KERNEL);
- if (mxt->rid_map == NULL) {
- printk(KERN_WARNING "maXTouch: Can't allocate memory!\n");
- error = -ENOMEM;
- goto err_rid_map_alloc;
- }
- mxt->messages = kzalloc(mxt->message_size * MXT_MESSAGE_BUFFER_SIZE,
- GFP_KERNEL);
- if (mxt->messages == NULL) {
- printk(KERN_WARNING "maXTouch: Can't allocate memory!\n");
- error = -ENOMEM;
- goto err_msg_alloc;
- }
- mxt->last_message = kzalloc(mxt->message_size, GFP_KERNEL);
- if (mxt->last_message == NULL) {
- printk(KERN_WARNING "maXTouch: Can't allocate memory!\n");
- error = -ENOMEM;
- goto err_msg_alloc;
- }
- mxt->report_id_count = report_id_count;
- if (report_id_count > 254) { /* 0 & 255 are reserved */
- dev_err(&client->dev,
- "Too many maXTouch report id's [%d]\n",
- report_id_count);
- error = -ENXIO;
- goto err_max_rid;
- }
- /* Create a mapping from report id to object type */
- report_id = 1; /* Start from 1, 0 is reserved. */
- /* Create table associating report id's with objects & instances */
- for (i = 0; i < mxt->device_info.num_objs; i++) {
- for (object_instance = 0;
- object_instance < object_table[i].instances;
- object_instance++){
- first_report_id = report_id;
- for (object_report_id = 0;
- object_report_id < object_table[i].num_report_ids;
- object_report_id++) {
- mxt->rid_map[report_id].object =
- object_table[i].type;
- mxt->rid_map[report_id].instance =
- object_instance;
- mxt->rid_map[report_id].first_rid =
- first_report_id;
- report_id++;
- }
- }
- }
- /* Read 3 byte CRC */
- error = mxt_read_block(client, object_info_address, 3, buf);
- if (error < 0) {
- mxt->read_fail_counter++;
- dev_err(&client->dev, "Error reading CRC\n");
- }
- crc = (buf[2] << 16) | (buf[1] << 8) | buf[0];
- if (calculate_infoblock_crc(&calculated_crc, raw_ib_data,
- ib_pointer)) {
- printk(KERN_WARNING "Error while calculating CRC!\n");
- calculated_crc = 0;
- }
- kfree(raw_ib_data);
- mxt_debug(DEBUG_TRACE, "\nReported info block CRC = 0x%6X\n", crc);
- mxt_debug(DEBUG_TRACE, "Calculated info block CRC = 0x%6X\n\n",
- calculated_crc);
-
- if (crc == calculated_crc) {
- mxt->info_block_crc = crc;
- } else {
- mxt->info_block_crc = 0;
- printk(KERN_ALERT "maXTouch: Info block CRC invalid!\n");
- }
- if (debug >= DEBUG_VERBOSE) {
- dev_info(&client->dev, "maXTouch: %d Objects\n",
- mxt->device_info.num_objs);
- for (i = 0; i < mxt->device_info.num_objs; i++) {
- dev_info(&client->dev, "Type:\t\t\t[%d]: %s\n",
- object_table[i].type,
- object_type_name[object_table[i].type]);
- dev_info(&client->dev, "\tAddress:\t0x%04X\n",
- object_table[i].chip_addr);
- dev_info(&client->dev, "\tSize:\t\t%d Bytes\n",
- object_table[i].size);
- dev_info(&client->dev, "\tInstances:\t%d\n",
- object_table[i].instances);
- dev_info(&client->dev, "\tReport Id's:\t%d\n",
- object_table[i].num_report_ids);
- }
- }
- return 0;
- err_max_rid:
- kfree(mxt->last_message);
- err_msg_alloc:
- kfree(mxt->rid_map);
- err_rid_map_alloc:
- err_object_read:
- kfree(raw_ib_data);
- err_ib_alloc:
- kfree(object_table);
- err_object_table_alloc:
- return error;
- }
- #if defined(CONFIG_PM)
- static int mxt_suspend(struct device *dev)
- {
- struct mxt_data *mxt = dev_get_drvdata(dev);
- int error, i;
- u8 t7_deepsl_data[T7_DATA_SIZE];
- u16 t7_addr;
- if (device_may_wakeup(dev)) {
- enable_irq_wake(mxt->irq);
- return 0;
- }
- disable_irq(mxt->irq);
- flush_delayed_work_sync(&mxt->dwork);
- for (i = 0; i < T7_DATA_SIZE; i++)
- t7_deepsl_data[i] = 0;
- t7_addr = MXT_BASE_ADDR(MXT_GEN_POWERCONFIG_T7, mxt);
- /* save current power state values */
- error = mxt_read_block(mxt->client, t7_addr,
- ARRAY_SIZE(mxt->t7_data), mxt->t7_data);
- if (error < 0)
- goto err_enable_irq;
- /* configure deep sleep mode */
- error = mxt_write_block(mxt->client, t7_addr,
- ARRAY_SIZE(t7_deepsl_data), t7_deepsl_data);
- if (error < 0)
- goto err_enable_irq;
- /* power off the device */
- if (mxt->power_on) {
- error = mxt->power_on(false);
- if (error) {
- dev_err(dev, "power off failed");
- goto err_write_block;
- }
- }
- mxt->is_suspended = true;
- return 0;
- err_write_block:
- mxt_write_block(mxt->client, t7_addr,
- ARRAY_SIZE(mxt->t7_data), mxt->t7_data);
- err_enable_irq:
- enable_irq(mxt->irq);
- return error;
- }
- static int mxt_resume(struct device *dev)
- {
- struct mxt_data *mxt = dev_get_drvdata(dev);
- int error;
- u16 t7_addr;
- if (device_may_wakeup(dev)) {
- disable_irq_wake(mxt->irq);
- return 0;
- }
- if (!mxt->is_suspended)
- return 0;
- /* power on the device */
- if (mxt->power_on) {
- error = mxt->power_on(true);
- if (error) {
- dev_err(dev, "power on failed");
- return error;
- }
- }
- t7_addr = MXT_BASE_ADDR(MXT_GEN_POWERCONFIG_T7, mxt);
- /* restore the old power state values */
- error = mxt_write_block(mxt->client, t7_addr,
- ARRAY_SIZE(mxt->t7_data), mxt->t7_data);
- if (error < 0)
- goto err_write_block;
- /* Make sure we just didn't miss a interrupt. */
- if (mxt->read_chg() == 0)
- schedule_delayed_work(&mxt->dwork, 0);
- else
- enable_irq(mxt->irq);
- mxt->is_suspended = false;
- return 0;
- err_write_block:
- if (mxt->power_on)
- mxt->power_on(false);
- return error;
- }
- #if defined(CONFIG_HAS_EARLYSUSPEND)
- static void mxt_early_suspend(struct early_suspend *h)
- {
- struct mxt_data *mxt = container_of(h, struct mxt_data, early_suspend);
- mxt_suspend(&mxt->client->dev);
- }
- static void mxt_late_resume(struct early_suspend *h)
- {
- struct mxt_data *mxt = container_of(h, struct mxt_data, early_suspend);
- mxt_resume(&mxt->client->dev);
- }
- #endif
- static const struct dev_pm_ops mxt_pm_ops = {
- #ifndef CONFIG_HAS_EARLYSUSPEND
- .suspend = mxt_suspend,
- .resume = mxt_resume,
- #endif
- };
- #endif
- static int __devinit mxt_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
- {
- struct mxt_data *mxt;
- struct maxtouch_platform_data *pdata;
- struct input_dev *input;
- u8 *id_data;
- u8 *t38_data;
- u16 t38_addr;
- int error;
- mxt_debug(DEBUG_INFO, "mXT224: mxt_probe\n");
- if (client == NULL) {
- pr_debug("maXTouch: client == NULL\n");
- return -EINVAL;
- } else if (client->adapter == NULL) {
- pr_debug("maXTouch: client->adapter == NULL\n");
- return -EINVAL;
- } else if (&client->dev == NULL) {
- pr_debug("maXTouch: client->dev == NULL\n");
- return -EINVAL;
- } else if (&client->adapter->dev == NULL) {
- pr_debug("maXTouch: client->adapter->dev == NULL\n");
- return -EINVAL;
- } else if (id == NULL) {
- pr_debug("maXTouch: id == NULL\n");
- return -EINVAL;
- }
- /* Enable runtime PM ops, start in ACTIVE mode */
- error = pm_runtime_set_active(&client->dev);
- if (error < 0)
- dev_dbg(&client->dev, "unable to set runtime pm state\n");
- pm_runtime_enable(&client->dev);
- mxt_debug(DEBUG_INFO, "maXTouch driver v. %s\n", DRIVER_VERSION);
- mxt_debug(DEBUG_INFO, "\t \"%s\"\n", client->name);
- mxt_debug(DEBUG_INFO, "\taddr:\t0x%04x\n", client->addr);
- mxt_debug(DEBUG_INFO, "\tirq:\t%d\n", client->irq);
- mxt_debug(DEBUG_INFO, "\tflags:\t0x%04x\n", client->flags);
- mxt_debug(DEBUG_INFO, "\tadapter:\"%s\"\n", client->adapter->name);
- mxt_debug(DEBUG_INFO, "\tdevice:\t\"%s\"\n", client->dev.init_name);
- mxt_debug(DEBUG_TRACE, "maXTouch driver functionality OK\n");
- /* Allocate structure - we need it to identify device */
- mxt = kzalloc(sizeof(struct mxt_data), GFP_KERNEL);
- if (mxt == NULL) {
- dev_err(&client->dev, "insufficient memory\n");
- error = -ENOMEM;
- goto err_mxt_alloc;
- }
- id_data = kmalloc(MXT_ID_BLOCK_SIZE, GFP_KERNEL);
- if (id_data == NULL) {
- dev_err(&client->dev, "insufficient memory\n");
- error = -ENOMEM;
- goto err_id_alloc;
- }
- input = input_allocate_device();
- if (!input) {
- dev_err(&client->dev, "error allocating input device\n");
- error = -ENOMEM;
- goto err_input_dev_alloc;
- }
- /* Initialize Platform data */
- pdata = client->dev.platform_data;
- if (pdata == NULL) {
- dev_err(&client->dev, "platform data is required!\n");
- error = -EINVAL;
- goto err_pdata;
- }
- if (debug >= DEBUG_TRACE)
- printk(KERN_INFO "Platform OK: pdata = 0x%08x\n",
- (unsigned int) pdata);
- mxt->is_suspended = false;
- mxt->read_fail_counter = 0;
- mxt->message_counter = 0;
- if (pdata->min_x)
- mxt->min_x_val = pdata->min_x;
- else
- mxt->min_x_val = 0;
- if (pdata->min_y)
- mxt->min_y_val = pdata->min_y;
- else
- mxt->min_y_val = 0;
- mxt->max_x_val = pdata->max_x;
- mxt->max_y_val = pdata->max_y;
- /* Get data that is defined in board specific code. */
- mxt->init_hw = pdata->init_platform_hw;
- mxt->exit_hw = pdata->exit_platform_hw;
- mxt->power_on = pdata->power_on;
- mxt->read_chg = pdata->read_chg;
- if (pdata->valid_interrupt != NULL)
- mxt->valid_interrupt = pdata->valid_interrupt;
- else
- mxt->valid_interrupt = mxt_valid_interrupt_dummy;
- if (mxt->init_hw) {
- error = mxt->init_hw(client);
- if (error) {
- dev_err(&client->dev, "hw init failed");
- goto err_init_hw;
- }
- }
- /* power on the device */
- if (mxt->power_on) {
- error = mxt->power_on(true);
- if (error) {
- dev_err(&client->dev, "power on failed");
- goto err_pwr_on;
- }
- }
- if (debug >= DEBUG_TRACE)
- printk(KERN_INFO "maXTouch driver identifying chip\n");
- if (mxt_identify(client, mxt, id_data) < 0) {
- dev_err(&client->dev, "Chip could not be identified\n");
- error = -ENODEV;
- goto err_identify;
- }
- /* Chip is valid and active. */
- if (debug >= DEBUG_TRACE)
- printk(KERN_INFO "maXTouch driver allocating input device\n");
- mxt->client = client;
- mxt->input = input;
- INIT_DELAYED_WORK(&mxt->dwork, mxt_worker);
- mutex_init(&mxt->debug_mutex);
- mutex_init(&mxt->msg_mutex);
- mxt_debug(DEBUG_TRACE, "maXTouch driver creating device name\n");
- snprintf(
- mxt->phys_name,
- sizeof(mxt->phys_name),
- "%s/input0",
- dev_name(&client->dev)
- );
- input->name = "Atmel maXTouch Touchscreen controller";
- input->phys = mxt->phys_name;
- input->id.bustype = BUS_I2C;
- input->dev.parent = &client->dev;
- mxt_debug(DEBUG_INFO, "maXTouch name: \"%s\"\n", input->name);
- mxt_debug(DEBUG_INFO, "maXTouch phys: \"%s\"\n", input->phys);
- mxt_debug(DEBUG_INFO, "maXTouch driver setting abs parameters\n");
-
- set_bit(BTN_TOUCH, input->keybit);
- set_bit(INPUT_PROP_DIRECT, input->propbit);
- /* Single touch */
- input_set_abs_params(input, ABS_X, mxt->min_x_val,
- mxt->max_x_val, 0, 0);
- input_set_abs_params(input, ABS_Y, mxt->min_y_val,
- mxt->max_y_val, 0, 0);
- input_set_abs_params(input, ABS_PRESSURE, 0, MXT_MAX_REPORTED_PRESSURE,
- 0, 0);
- input_set_abs_params(input, ABS_TOOL_WIDTH, 0, MXT_MAX_REPORTED_WIDTH,
- 0, 0);
- /* Multitouch */
- input_set_abs_params(input, ABS_MT_POSITION_X, mxt->min_x_val,
- mxt->max_x_val, 0, 0);
- input_set_abs_params(input, ABS_MT_POSITION_Y, mxt->min_y_val,
- mxt->max_y_val, 0, 0);
- input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, MXT_MAX_TOUCH_SIZE,
- 0, 0);
- input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, MXT_MAX_NUM_TOUCHES,
- 0, 0);
-
- __set_bit(EV_ABS, input->evbit);
- __set_bit(EV_SYN, input->evbit);
- __set_bit(EV_KEY, input->evbit);
- __set_bit(EV_MSC, input->evbit);
- input->mscbit[0] = BIT_MASK(MSC_GESTURE);
- mxt_debug(DEBUG_TRACE, "maXTouch driver setting client data\n");
- i2c_set_clientdata(client, mxt);
- mxt_debug(DEBUG_TRACE, "maXTouch driver setting drv data\n");
- input_set_drvdata(input, mxt);
- mxt_debug(DEBUG_TRACE, "maXTouch driver input register device\n");
- error = input_register_device(mxt->input);
- if (error < 0) {
- dev_err(&client->dev,
- "Failed to register input device\n");
- goto err_register_device;
- }
- error = mxt_read_object_table(client, mxt, id_data);
- if (error < 0)
- goto err_read_ot;
- /* Create debugfs entries. */
- mxt->debug_dir = debugfs_create_dir("maXTouch", NULL);
- if (mxt->debug_dir == ERR_PTR(-ENODEV)) {
- /* debugfs is not enabled. */
- printk(KERN_WARNING "debugfs not enabled in kernel\n");
- } else if (mxt->debug_dir == NULL) {
- printk(KERN_WARNING "error creating debugfs dir\n");
- } else {
- mxt_debug(DEBUG_TRACE, "created \"maXTouch\" debugfs dir\n");
-
- debugfs_create_file("deltas", S_IRUSR, mxt->debug_dir, mxt,
- &delta_fops);
- debugfs_create_file("refs", S_IRUSR, mxt->debug_dir, mxt,
- &refs_fops);
- }
- /* Create character device nodes for reading & writing registers */
- mxt->mxt_class = class_create(THIS_MODULE, "maXTouch_memory");
- if (IS_ERR(mxt->mxt_class)){
- printk(KERN_WARNING "class create failed! exiting...");
- goto err_class_create;
-
- }
- /* 2 numbers; one for memory and one for messages */
- error = alloc_chrdev_region(&mxt->dev_num, 0, 2,
- "maXTouch_memory");
- mxt_debug(DEBUG_VERBOSE,
- "device number %d allocated!\n", MAJOR(mxt->dev_num));
- if (error){
- printk(KERN_WARNING "Error registering device\n");
- }
- cdev_init(&mxt->cdev, &mxt_memory_fops);
- cdev_init(&mxt->cdev_messages, &mxt_message_fops);
-
- mxt_debug(DEBUG_VERBOSE, "cdev initialized\n");
- mxt->cdev.owner = THIS_MODULE;
- mxt->cdev_messages.owner = THIS_MODULE;
-
- error = cdev_add(&mxt->cdev, mxt->dev_num, 1);
- if (error){
- printk(KERN_WARNING "Bad cdev\n");
- }
-
- error = cdev_add(&mxt->cdev_messages, mxt->dev_num + 1, 1);
- if (error){
- printk(KERN_WARNING "Bad cdev\n");
- }
-
- mxt_debug(DEBUG_VERBOSE, "cdev added\n");
-
- device_create(mxt->mxt_class, NULL, MKDEV(MAJOR(mxt->dev_num), 0), NULL,
- "maXTouch");
- device_create(mxt->mxt_class, NULL, MKDEV(MAJOR(mxt->dev_num), 1), NULL,
- "maXTouch_messages");
- mxt->msg_buffer_startp = 0;
- mxt->msg_buffer_endp = 0;
- /* Allocate the interrupt */
- mxt_debug(DEBUG_TRACE, "maXTouch driver allocating interrupt...\n");
- mxt->irq = client->irq;
- mxt->valid_irq_counter = 0;
- mxt->invalid_irq_counter = 0;
- mxt->irq_counter = 0;
- if (mxt->irq) {
- /* Try to request IRQ with falling edge first. This is
- * not always supported. If it fails, try with any edge. */
- error = request_irq(mxt->irq,
- mxt_irq_handler,
- IRQF_TRIGGER_FALLING,
- client->dev.driver->name,
- mxt);
- if (error < 0) {
- /* TODO: why only 0 works on STK1000? */
- error = request_irq(mxt->irq,
- mxt_irq_handler,
- 0,
- client->dev.driver->name,
- mxt);
- }
- if (error < 0) {
- dev_err(&client->dev,
- "failed to allocate irq %d\n", mxt->irq);
- goto err_irq;
- }
- }
- if (debug > DEBUG_INFO)
- dev_info(&client->dev, "touchscreen, irq %d\n", mxt->irq);
-
- t38_data = kmalloc(t38_size*sizeof(u8), GFP_KERNEL);
- if (t38_data == NULL) {
- dev_err(&client->dev, "insufficient memory\n");
- error = -ENOMEM;
- goto err_t38;
- }
- t38_addr = MXT_BASE_ADDR(MXT_USER_INFO_T38, mxt);
- mxt_read_block(client, t38_addr, t38_size, t38_data);
- dev_info(&client->dev, "VERSION:%02x.%02x.%02x, DATE: %d/%d/%d\n",
- t38_data[0], t38_data[1], t38_data[2],
- t38_data[3], t38_data[4], t38_data[5]);
- /* Schedule a worker routine to read any messages that might have
- * been sent before interrupts were enabled. */
- cancel_delayed_work(&mxt->dwork);
- disable_irq(mxt->irq);
- schedule_delayed_work(&mxt->dwork, 0);
- kfree(t38_data);
- kfree(id_data);
- device_init_wakeup(&client->dev, pdata->wakeup);
- #if defined(CONFIG_HAS_EARLYSUSPEND)
- mxt->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN +
- MXT_SUSPEND_LEVEL;
- mxt->early_suspend.suspend = mxt_early_suspend;
- mxt->early_suspend.resume = mxt_late_resume;
- register_early_suspend(&mxt->early_suspend);
- #endif
- return 0;
- err_t38:
- free_irq(mxt->irq, mxt);
- err_irq:
- kfree(mxt->rid_map);
- kfree(mxt->object_table);
- kfree(mxt->last_message);
- err_class_create:
- if (mxt->debug_dir)
- debugfs_remove(mxt->debug_dir);
- kfree(mxt->last_message);
- kfree(mxt->rid_map);
- kfree(mxt->object_table);
- err_read_ot:
- input_unregister_device(mxt->input);
- mxt->input = NULL;
- err_register_device:
- mutex_destroy(&mxt->debug_mutex);
- mutex_destroy(&mxt->msg_mutex);
- err_identify:
- if (mxt->power_on)
- mxt->power_on(false);
- err_pwr_on:
- if (mxt->exit_hw != NULL)
- mxt->exit_hw(client);
- err_init_hw:
- err_pdata:
- input_free_device(input);
- err_input_dev_alloc:
- kfree(id_data);
- err_id_alloc:
- kfree(mxt);
- err_mxt_alloc:
- pm_runtime_set_suspended(&client->dev);
- pm_runtime_disable(&client->dev);
- return error;
- }
- static int __devexit mxt_remove(struct i2c_client *client)
- {
- struct mxt_data *mxt;
- pm_runtime_set_suspended(&client->dev);
- pm_runtime_disable(&client->dev);
- mxt = i2c_get_clientdata(client);
- /* Remove debug dir entries */
- debugfs_remove_recursive(mxt->debug_dir);
- device_init_wakeup(&client->dev, 0);
- #if defined(CONFIG_HAS_EARLYSUSPEND)
- unregister_early_suspend(&mxt->early_suspend);
- #endif
- if (mxt != NULL) {
- if (mxt->power_on)
- mxt->power_on(false);
- if (mxt->exit_hw != NULL)
- mxt->exit_hw(client);
- if (mxt->irq) {
- free_irq(mxt->irq, mxt);
- }
- unregister_chrdev_region(mxt->dev_num, 2);
- device_destroy(mxt->mxt_class, MKDEV(MAJOR(mxt->dev_num), 0));
- device_destroy(mxt->mxt_class, MKDEV(MAJOR(mxt->dev_num), 1));
- cdev_del(&mxt->cdev);
- cdev_del(&mxt->cdev_messages);
- cancel_delayed_work_sync(&mxt->dwork);
- input_unregister_device(mxt->input);
- class_destroy(mxt->mxt_class);
- debugfs_remove(mxt->debug_dir);
- kfree(mxt->rid_map);
- kfree(mxt->object_table);
- kfree(mxt->last_message);
- }
- kfree(mxt);
- i2c_set_clientdata(client, NULL);
- if (debug >= DEBUG_TRACE)
- dev_info(&client->dev, "Touchscreen unregistered\n");
- return 0;
- }
- static const struct i2c_device_id mxt_idtable[] = {
- {"maXTouch", 0,},
- { }
- };
- MODULE_DEVICE_TABLE(i2c, mxt_idtable);
- static struct i2c_driver mxt_driver = {
- .driver = {
- .name = "maXTouch",
- .owner = THIS_MODULE,
- #if defined(CONFIG_PM)
- .pm = &mxt_pm_ops,
- #endif
- },
- .id_table = mxt_idtable,
- .probe = mxt_probe,
- .remove = __devexit_p(mxt_remove),
- };
- static int __init mxt_init(void)
- {
- int err;
- err = i2c_add_driver(&mxt_driver);
- if (err) {
- printk(KERN_WARNING "Adding maXTouch driver failed "
- "(errno = %d)\n", err);
- } else {
- mxt_debug(DEBUG_TRACE, "Successfully added driver %s\n",
- mxt_driver.driver.name);
- }
- return err;
- }
- static void __exit mxt_cleanup(void)
- {
- i2c_del_driver(&mxt_driver);
- }
- module_init(mxt_init);
- module_exit(mxt_cleanup);
- MODULE_AUTHOR("Iiro Valkonen");
- MODULE_DESCRIPTION("Driver for Atmel maXTouch Touchscreen Controller");
- MODULE_LICENSE("GPL");
|