| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
- * Azoteq IQS7210A/7211A/E Trackpad/Touchscreen Controller
- *
- * Copyright (C) 2023 Jeff LaBundy <jeff@labundy.com>
- */
- #include <linux/bits.h>
- #include <linux/delay.h>
- #include <linux/device.h>
- #include <linux/err.h>
- #include <linux/gpio/consumer.h>
- #include <linux/i2c.h>
- #include <linux/input.h>
- #include <linux/input/mt.h>
- #include <linux/input/touchscreen.h>
- #include <linux/interrupt.h>
- #include <linux/iopoll.h>
- #include <linux/kernel.h>
- #include <linux/list.h>
- #include <linux/module.h>
- #include <linux/of_device.h>
- #include <linux/property.h>
- #include <linux/slab.h>
- #include <linux/unaligned.h>
- #define IQS7211_PROD_NUM 0x00
- #define IQS7211_EVENT_MASK_ALL GENMASK(14, 8)
- #define IQS7211_EVENT_MASK_ALP BIT(13)
- #define IQS7211_EVENT_MASK_BTN BIT(12)
- #define IQS7211_EVENT_MASK_ATI BIT(11)
- #define IQS7211_EVENT_MASK_MOVE BIT(10)
- #define IQS7211_EVENT_MASK_GSTR BIT(9)
- #define IQS7211_EVENT_MODE BIT(8)
- #define IQS7211_COMMS_ERROR 0xEEEE
- #define IQS7211_COMMS_RETRY_MS 50
- #define IQS7211_COMMS_SLEEP_US 100
- #define IQS7211_COMMS_TIMEOUT_US (100 * USEC_PER_MSEC)
- #define IQS7211_RESET_TIMEOUT_MS 150
- #define IQS7211_START_TIMEOUT_US (1 * USEC_PER_SEC)
- #define IQS7211_NUM_RETRIES 5
- #define IQS7211_NUM_CRX 8
- #define IQS7211_MAX_CTX 13
- #define IQS7211_MAX_CONTACTS 2
- #define IQS7211_MAX_CYCLES 21
- /*
- * The following delay is used during instances that must wait for the open-
- * drain RDY pin to settle. Its value is calculated as 5*R*C, where R and C
- * represent typical datasheet values of 4.7k and 100 nF, respectively.
- */
- #define iqs7211_irq_wait() usleep_range(2500, 2600)
- enum iqs7211_dev_id {
- IQS7210A,
- IQS7211A,
- IQS7211E,
- };
- enum iqs7211_comms_mode {
- IQS7211_COMMS_MODE_WAIT,
- IQS7211_COMMS_MODE_FREE,
- IQS7211_COMMS_MODE_FORCE,
- };
- struct iqs7211_reg_field_desc {
- struct list_head list;
- u8 addr;
- u16 mask;
- u16 val;
- };
- enum iqs7211_reg_key_id {
- IQS7211_REG_KEY_NONE,
- IQS7211_REG_KEY_PROX,
- IQS7211_REG_KEY_TOUCH,
- IQS7211_REG_KEY_TAP,
- IQS7211_REG_KEY_HOLD,
- IQS7211_REG_KEY_PALM,
- IQS7211_REG_KEY_AXIAL_X,
- IQS7211_REG_KEY_AXIAL_Y,
- IQS7211_REG_KEY_RESERVED
- };
- enum iqs7211_reg_grp_id {
- IQS7211_REG_GRP_TP,
- IQS7211_REG_GRP_BTN,
- IQS7211_REG_GRP_ALP,
- IQS7211_REG_GRP_SYS,
- IQS7211_NUM_REG_GRPS
- };
- static const char * const iqs7211_reg_grp_names[IQS7211_NUM_REG_GRPS] = {
- [IQS7211_REG_GRP_TP] = "trackpad",
- [IQS7211_REG_GRP_BTN] = "button",
- [IQS7211_REG_GRP_ALP] = "alp",
- };
- static const u16 iqs7211_reg_grp_masks[IQS7211_NUM_REG_GRPS] = {
- [IQS7211_REG_GRP_TP] = IQS7211_EVENT_MASK_GSTR,
- [IQS7211_REG_GRP_BTN] = IQS7211_EVENT_MASK_BTN,
- [IQS7211_REG_GRP_ALP] = IQS7211_EVENT_MASK_ALP,
- };
- struct iqs7211_event_desc {
- const char *name;
- u16 mask;
- u16 enable;
- enum iqs7211_reg_grp_id reg_grp;
- enum iqs7211_reg_key_id reg_key;
- };
- static const struct iqs7211_event_desc iqs7210a_kp_events[] = {
- {
- .mask = BIT(10),
- .enable = BIT(13) | BIT(12),
- .reg_grp = IQS7211_REG_GRP_ALP,
- },
- {
- .name = "event-prox",
- .mask = BIT(2),
- .enable = BIT(5) | BIT(4),
- .reg_grp = IQS7211_REG_GRP_BTN,
- .reg_key = IQS7211_REG_KEY_PROX,
- },
- {
- .name = "event-touch",
- .mask = BIT(3),
- .enable = BIT(5) | BIT(4),
- .reg_grp = IQS7211_REG_GRP_BTN,
- .reg_key = IQS7211_REG_KEY_TOUCH,
- },
- {
- .name = "event-tap",
- .mask = BIT(0),
- .enable = BIT(0),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_TAP,
- },
- {
- .name = "event-hold",
- .mask = BIT(1),
- .enable = BIT(1),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_HOLD,
- },
- {
- .name = "event-swipe-x-neg",
- .mask = BIT(2),
- .enable = BIT(2),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_AXIAL_X,
- },
- {
- .name = "event-swipe-x-pos",
- .mask = BIT(3),
- .enable = BIT(3),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_AXIAL_X,
- },
- {
- .name = "event-swipe-y-pos",
- .mask = BIT(4),
- .enable = BIT(4),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_AXIAL_Y,
- },
- {
- .name = "event-swipe-y-neg",
- .mask = BIT(5),
- .enable = BIT(5),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_AXIAL_Y,
- },
- };
- static const struct iqs7211_event_desc iqs7211a_kp_events[] = {
- {
- .mask = BIT(14),
- .reg_grp = IQS7211_REG_GRP_ALP,
- },
- {
- .name = "event-tap",
- .mask = BIT(0),
- .enable = BIT(0),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_TAP,
- },
- {
- .name = "event-hold",
- .mask = BIT(1),
- .enable = BIT(1),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_HOLD,
- },
- {
- .name = "event-swipe-x-neg",
- .mask = BIT(2),
- .enable = BIT(2),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_AXIAL_X,
- },
- {
- .name = "event-swipe-x-pos",
- .mask = BIT(3),
- .enable = BIT(3),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_AXIAL_X,
- },
- {
- .name = "event-swipe-y-pos",
- .mask = BIT(4),
- .enable = BIT(4),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_AXIAL_Y,
- },
- {
- .name = "event-swipe-y-neg",
- .mask = BIT(5),
- .enable = BIT(5),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_AXIAL_Y,
- },
- };
- static const struct iqs7211_event_desc iqs7211e_kp_events[] = {
- {
- .mask = BIT(14),
- .reg_grp = IQS7211_REG_GRP_ALP,
- },
- {
- .name = "event-tap",
- .mask = BIT(0),
- .enable = BIT(0),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_TAP,
- },
- {
- .name = "event-tap-double",
- .mask = BIT(1),
- .enable = BIT(1),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_TAP,
- },
- {
- .name = "event-tap-triple",
- .mask = BIT(2),
- .enable = BIT(2),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_TAP,
- },
- {
- .name = "event-hold",
- .mask = BIT(3),
- .enable = BIT(3),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_HOLD,
- },
- {
- .name = "event-palm",
- .mask = BIT(4),
- .enable = BIT(4),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_PALM,
- },
- {
- .name = "event-swipe-x-pos",
- .mask = BIT(8),
- .enable = BIT(8),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_AXIAL_X,
- },
- {
- .name = "event-swipe-x-neg",
- .mask = BIT(9),
- .enable = BIT(9),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_AXIAL_X,
- },
- {
- .name = "event-swipe-y-pos",
- .mask = BIT(10),
- .enable = BIT(10),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_AXIAL_Y,
- },
- {
- .name = "event-swipe-y-neg",
- .mask = BIT(11),
- .enable = BIT(11),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_AXIAL_Y,
- },
- {
- .name = "event-swipe-x-pos-hold",
- .mask = BIT(12),
- .enable = BIT(12),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_HOLD,
- },
- {
- .name = "event-swipe-x-neg-hold",
- .mask = BIT(13),
- .enable = BIT(13),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_HOLD,
- },
- {
- .name = "event-swipe-y-pos-hold",
- .mask = BIT(14),
- .enable = BIT(14),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_HOLD,
- },
- {
- .name = "event-swipe-y-neg-hold",
- .mask = BIT(15),
- .enable = BIT(15),
- .reg_grp = IQS7211_REG_GRP_TP,
- .reg_key = IQS7211_REG_KEY_HOLD,
- },
- };
- struct iqs7211_dev_desc {
- const char *tp_name;
- const char *kp_name;
- u16 prod_num;
- u16 show_reset;
- u16 ati_error[IQS7211_NUM_REG_GRPS];
- u16 ati_start[IQS7211_NUM_REG_GRPS];
- u16 suspend;
- u16 ack_reset;
- u16 comms_end;
- u16 comms_req;
- int charge_shift;
- int info_offs;
- int gesture_offs;
- int contact_offs;
- u8 sys_stat;
- u8 sys_ctrl;
- u8 alp_config;
- u8 tp_config;
- u8 exp_file;
- u8 kp_enable[IQS7211_NUM_REG_GRPS];
- u8 gesture_angle;
- u8 rx_tx_map;
- u8 cycle_alloc[2];
- u8 cycle_limit[2];
- const struct iqs7211_event_desc *kp_events;
- int num_kp_events;
- int min_crx_alp;
- int num_ctx;
- };
- static const struct iqs7211_dev_desc iqs7211_devs[] = {
- [IQS7210A] = {
- .tp_name = "iqs7210a_trackpad",
- .kp_name = "iqs7210a_keys",
- .prod_num = 944,
- .show_reset = BIT(15),
- .ati_error = {
- [IQS7211_REG_GRP_TP] = BIT(12),
- [IQS7211_REG_GRP_BTN] = BIT(0),
- [IQS7211_REG_GRP_ALP] = BIT(8),
- },
- .ati_start = {
- [IQS7211_REG_GRP_TP] = BIT(13),
- [IQS7211_REG_GRP_BTN] = BIT(1),
- [IQS7211_REG_GRP_ALP] = BIT(9),
- },
- .suspend = BIT(11),
- .ack_reset = BIT(7),
- .comms_end = BIT(2),
- .comms_req = BIT(1),
- .charge_shift = 4,
- .info_offs = 0,
- .gesture_offs = 1,
- .contact_offs = 4,
- .sys_stat = 0x0A,
- .sys_ctrl = 0x35,
- .alp_config = 0x39,
- .tp_config = 0x4E,
- .exp_file = 0x57,
- .kp_enable = {
- [IQS7211_REG_GRP_TP] = 0x58,
- [IQS7211_REG_GRP_BTN] = 0x37,
- [IQS7211_REG_GRP_ALP] = 0x37,
- },
- .gesture_angle = 0x5F,
- .rx_tx_map = 0x60,
- .cycle_alloc = { 0x66, 0x75, },
- .cycle_limit = { 10, 6, },
- .kp_events = iqs7210a_kp_events,
- .num_kp_events = ARRAY_SIZE(iqs7210a_kp_events),
- .min_crx_alp = 4,
- .num_ctx = IQS7211_MAX_CTX - 1,
- },
- [IQS7211A] = {
- .tp_name = "iqs7211a_trackpad",
- .kp_name = "iqs7211a_keys",
- .prod_num = 763,
- .show_reset = BIT(7),
- .ati_error = {
- [IQS7211_REG_GRP_TP] = BIT(3),
- [IQS7211_REG_GRP_ALP] = BIT(5),
- },
- .ati_start = {
- [IQS7211_REG_GRP_TP] = BIT(5),
- [IQS7211_REG_GRP_ALP] = BIT(6),
- },
- .ack_reset = BIT(7),
- .comms_req = BIT(4),
- .charge_shift = 0,
- .info_offs = 0,
- .gesture_offs = 1,
- .contact_offs = 4,
- .sys_stat = 0x10,
- .sys_ctrl = 0x50,
- .tp_config = 0x60,
- .alp_config = 0x72,
- .exp_file = 0x74,
- .kp_enable = {
- [IQS7211_REG_GRP_TP] = 0x80,
- },
- .gesture_angle = 0x87,
- .rx_tx_map = 0x90,
- .cycle_alloc = { 0xA0, 0xB0, },
- .cycle_limit = { 10, 8, },
- .kp_events = iqs7211a_kp_events,
- .num_kp_events = ARRAY_SIZE(iqs7211a_kp_events),
- .num_ctx = IQS7211_MAX_CTX - 1,
- },
- [IQS7211E] = {
- .tp_name = "iqs7211e_trackpad",
- .kp_name = "iqs7211e_keys",
- .prod_num = 1112,
- .show_reset = BIT(7),
- .ati_error = {
- [IQS7211_REG_GRP_TP] = BIT(3),
- [IQS7211_REG_GRP_ALP] = BIT(5),
- },
- .ati_start = {
- [IQS7211_REG_GRP_TP] = BIT(5),
- [IQS7211_REG_GRP_ALP] = BIT(6),
- },
- .suspend = BIT(11),
- .ack_reset = BIT(7),
- .comms_end = BIT(6),
- .comms_req = BIT(4),
- .charge_shift = 0,
- .info_offs = 1,
- .gesture_offs = 0,
- .contact_offs = 2,
- .sys_stat = 0x0E,
- .sys_ctrl = 0x33,
- .tp_config = 0x41,
- .alp_config = 0x36,
- .exp_file = 0x4A,
- .kp_enable = {
- [IQS7211_REG_GRP_TP] = 0x4B,
- },
- .gesture_angle = 0x55,
- .rx_tx_map = 0x56,
- .cycle_alloc = { 0x5D, 0x6C, },
- .cycle_limit = { 10, 11, },
- .kp_events = iqs7211e_kp_events,
- .num_kp_events = ARRAY_SIZE(iqs7211e_kp_events),
- .num_ctx = IQS7211_MAX_CTX,
- },
- };
- struct iqs7211_prop_desc {
- const char *name;
- enum iqs7211_reg_key_id reg_key;
- u8 reg_addr[IQS7211_NUM_REG_GRPS][ARRAY_SIZE(iqs7211_devs)];
- int reg_shift;
- int reg_width;
- int val_pitch;
- int val_min;
- int val_max;
- const char *label;
- };
- static const struct iqs7211_prop_desc iqs7211_props[] = {
- {
- .name = "azoteq,ati-frac-div-fine",
- .reg_addr = {
- [IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x1E,
- [IQS7211A] = 0x30,
- [IQS7211E] = 0x21,
- },
- [IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x22,
- },
- [IQS7211_REG_GRP_ALP] = {
- [IQS7210A] = 0x23,
- [IQS7211A] = 0x36,
- [IQS7211E] = 0x25,
- },
- },
- .reg_shift = 9,
- .reg_width = 5,
- .label = "ATI fine fractional divider",
- },
- {
- .name = "azoteq,ati-frac-mult-coarse",
- .reg_addr = {
- [IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x1E,
- [IQS7211A] = 0x30,
- [IQS7211E] = 0x21,
- },
- [IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x22,
- },
- [IQS7211_REG_GRP_ALP] = {
- [IQS7210A] = 0x23,
- [IQS7211A] = 0x36,
- [IQS7211E] = 0x25,
- },
- },
- .reg_shift = 5,
- .reg_width = 4,
- .label = "ATI coarse fractional multiplier",
- },
- {
- .name = "azoteq,ati-frac-div-coarse",
- .reg_addr = {
- [IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x1E,
- [IQS7211A] = 0x30,
- [IQS7211E] = 0x21,
- },
- [IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x22,
- },
- [IQS7211_REG_GRP_ALP] = {
- [IQS7210A] = 0x23,
- [IQS7211A] = 0x36,
- [IQS7211E] = 0x25,
- },
- },
- .reg_shift = 0,
- .reg_width = 5,
- .label = "ATI coarse fractional divider",
- },
- {
- .name = "azoteq,ati-comp-div",
- .reg_addr = {
- [IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x1F,
- [IQS7211E] = 0x22,
- },
- [IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x24,
- },
- [IQS7211_REG_GRP_ALP] = {
- [IQS7211E] = 0x26,
- },
- },
- .reg_shift = 0,
- .reg_width = 8,
- .val_max = 31,
- .label = "ATI compensation divider",
- },
- {
- .name = "azoteq,ati-comp-div",
- .reg_addr = {
- [IQS7211_REG_GRP_ALP] = {
- [IQS7210A] = 0x24,
- },
- },
- .reg_shift = 8,
- .reg_width = 8,
- .val_max = 31,
- .label = "ATI compensation divider",
- },
- {
- .name = "azoteq,ati-comp-div",
- .reg_addr = {
- [IQS7211_REG_GRP_TP] = {
- [IQS7211A] = 0x31,
- },
- [IQS7211_REG_GRP_ALP] = {
- [IQS7211A] = 0x37,
- },
- },
- .val_max = 31,
- .label = "ATI compensation divider",
- },
- {
- .name = "azoteq,ati-target",
- .reg_addr = {
- [IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x20,
- [IQS7211A] = 0x32,
- [IQS7211E] = 0x23,
- },
- [IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x27,
- },
- [IQS7211_REG_GRP_ALP] = {
- [IQS7210A] = 0x28,
- [IQS7211A] = 0x38,
- [IQS7211E] = 0x27,
- },
- },
- .label = "ATI target",
- },
- {
- .name = "azoteq,ati-base",
- .reg_addr[IQS7211_REG_GRP_ALP] = {
- [IQS7210A] = 0x26,
- },
- .reg_shift = 8,
- .reg_width = 8,
- .val_pitch = 8,
- .label = "ATI base",
- },
- {
- .name = "azoteq,ati-base",
- .reg_addr[IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x26,
- },
- .reg_shift = 0,
- .reg_width = 8,
- .val_pitch = 8,
- .label = "ATI base",
- },
- {
- .name = "azoteq,rate-active-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x29,
- [IQS7211A] = 0x40,
- [IQS7211E] = 0x28,
- },
- .label = "active mode report rate",
- },
- {
- .name = "azoteq,rate-touch-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x2A,
- [IQS7211A] = 0x41,
- [IQS7211E] = 0x29,
- },
- .label = "idle-touch mode report rate",
- },
- {
- .name = "azoteq,rate-idle-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x2B,
- [IQS7211A] = 0x42,
- [IQS7211E] = 0x2A,
- },
- .label = "idle mode report rate",
- },
- {
- .name = "azoteq,rate-lp1-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x2C,
- [IQS7211A] = 0x43,
- [IQS7211E] = 0x2B,
- },
- .label = "low-power mode 1 report rate",
- },
- {
- .name = "azoteq,rate-lp2-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x2D,
- [IQS7211A] = 0x44,
- [IQS7211E] = 0x2C,
- },
- .label = "low-power mode 2 report rate",
- },
- {
- .name = "azoteq,timeout-active-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x2E,
- [IQS7211A] = 0x45,
- [IQS7211E] = 0x2D,
- },
- .val_pitch = 1000,
- .label = "active mode timeout",
- },
- {
- .name = "azoteq,timeout-touch-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x2F,
- [IQS7211A] = 0x46,
- [IQS7211E] = 0x2E,
- },
- .val_pitch = 1000,
- .label = "idle-touch mode timeout",
- },
- {
- .name = "azoteq,timeout-idle-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x30,
- [IQS7211A] = 0x47,
- [IQS7211E] = 0x2F,
- },
- .val_pitch = 1000,
- .label = "idle mode timeout",
- },
- {
- .name = "azoteq,timeout-lp1-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x31,
- [IQS7211A] = 0x48,
- [IQS7211E] = 0x30,
- },
- .val_pitch = 1000,
- .label = "low-power mode 1 timeout",
- },
- {
- .name = "azoteq,timeout-lp2-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x32,
- [IQS7211E] = 0x31,
- },
- .reg_shift = 8,
- .reg_width = 8,
- .val_pitch = 1000,
- .val_max = 60000,
- .label = "trackpad reference value update rate",
- },
- {
- .name = "azoteq,timeout-lp2-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7211A] = 0x49,
- },
- .val_pitch = 1000,
- .val_max = 60000,
- .label = "trackpad reference value update rate",
- },
- {
- .name = "azoteq,timeout-ati-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x32,
- [IQS7211E] = 0x31,
- },
- .reg_width = 8,
- .val_pitch = 1000,
- .val_max = 60000,
- .label = "ATI error timeout",
- },
- {
- .name = "azoteq,timeout-ati-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7211A] = 0x35,
- },
- .val_pitch = 1000,
- .val_max = 60000,
- .label = "ATI error timeout",
- },
- {
- .name = "azoteq,timeout-comms-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x33,
- [IQS7211A] = 0x4A,
- [IQS7211E] = 0x32,
- },
- .label = "communication timeout",
- },
- {
- .name = "azoteq,timeout-press-ms",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x34,
- },
- .reg_width = 8,
- .val_pitch = 1000,
- .val_max = 60000,
- .label = "press timeout",
- },
- {
- .name = "azoteq,ati-mode",
- .reg_addr[IQS7211_REG_GRP_ALP] = {
- [IQS7210A] = 0x37,
- },
- .reg_shift = 15,
- .reg_width = 1,
- .label = "ATI mode",
- },
- {
- .name = "azoteq,ati-mode",
- .reg_addr[IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x37,
- },
- .reg_shift = 7,
- .reg_width = 1,
- .label = "ATI mode",
- },
- {
- .name = "azoteq,sense-mode",
- .reg_addr[IQS7211_REG_GRP_ALP] = {
- [IQS7210A] = 0x37,
- [IQS7211A] = 0x72,
- [IQS7211E] = 0x36,
- },
- .reg_shift = 8,
- .reg_width = 1,
- .label = "sensing mode",
- },
- {
- .name = "azoteq,sense-mode",
- .reg_addr[IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x37,
- },
- .reg_shift = 0,
- .reg_width = 2,
- .val_max = 2,
- .label = "sensing mode",
- },
- {
- .name = "azoteq,fosc-freq",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x38,
- [IQS7211A] = 0x52,
- [IQS7211E] = 0x35,
- },
- .reg_shift = 4,
- .reg_width = 1,
- .label = "core clock frequency selection",
- },
- {
- .name = "azoteq,fosc-trim",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x38,
- [IQS7211A] = 0x52,
- [IQS7211E] = 0x35,
- },
- .reg_shift = 0,
- .reg_width = 4,
- .label = "core clock frequency trim",
- },
- {
- .name = "azoteq,touch-exit",
- .reg_addr = {
- [IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x3B,
- [IQS7211A] = 0x53,
- [IQS7211E] = 0x38,
- },
- [IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x3E,
- },
- },
- .reg_shift = 8,
- .reg_width = 8,
- .label = "touch exit factor",
- },
- {
- .name = "azoteq,touch-enter",
- .reg_addr = {
- [IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x3B,
- [IQS7211A] = 0x53,
- [IQS7211E] = 0x38,
- },
- [IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x3E,
- },
- },
- .reg_shift = 0,
- .reg_width = 8,
- .label = "touch entrance factor",
- },
- {
- .name = "azoteq,thresh",
- .reg_addr = {
- [IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x3C,
- },
- [IQS7211_REG_GRP_ALP] = {
- [IQS7210A] = 0x3D,
- [IQS7211A] = 0x54,
- [IQS7211E] = 0x39,
- },
- },
- .label = "threshold",
- },
- {
- .name = "azoteq,debounce-exit",
- .reg_addr = {
- [IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x3F,
- },
- [IQS7211_REG_GRP_ALP] = {
- [IQS7210A] = 0x40,
- [IQS7211A] = 0x56,
- [IQS7211E] = 0x3A,
- },
- },
- .reg_shift = 8,
- .reg_width = 8,
- .label = "debounce exit factor",
- },
- {
- .name = "azoteq,debounce-enter",
- .reg_addr = {
- [IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x3F,
- },
- [IQS7211_REG_GRP_ALP] = {
- [IQS7210A] = 0x40,
- [IQS7211A] = 0x56,
- [IQS7211E] = 0x3A,
- },
- },
- .reg_shift = 0,
- .reg_width = 8,
- .label = "debounce entrance factor",
- },
- {
- .name = "azoteq,conv-frac",
- .reg_addr = {
- [IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x48,
- [IQS7211A] = 0x58,
- [IQS7211E] = 0x3D,
- },
- [IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x49,
- },
- [IQS7211_REG_GRP_ALP] = {
- [IQS7210A] = 0x4A,
- [IQS7211A] = 0x59,
- [IQS7211E] = 0x3E,
- },
- },
- .reg_shift = 8,
- .reg_width = 8,
- .label = "conversion frequency fractional divider",
- },
- {
- .name = "azoteq,conv-period",
- .reg_addr = {
- [IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x48,
- [IQS7211A] = 0x58,
- [IQS7211E] = 0x3D,
- },
- [IQS7211_REG_GRP_BTN] = {
- [IQS7210A] = 0x49,
- },
- [IQS7211_REG_GRP_ALP] = {
- [IQS7210A] = 0x4A,
- [IQS7211A] = 0x59,
- [IQS7211E] = 0x3E,
- },
- },
- .reg_shift = 0,
- .reg_width = 8,
- .label = "conversion period",
- },
- {
- .name = "azoteq,thresh",
- .reg_addr[IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x55,
- [IQS7211A] = 0x67,
- [IQS7211E] = 0x48,
- },
- .reg_shift = 0,
- .reg_width = 8,
- .label = "threshold",
- },
- {
- .name = "azoteq,contact-split",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x55,
- [IQS7211A] = 0x67,
- [IQS7211E] = 0x48,
- },
- .reg_shift = 8,
- .reg_width = 8,
- .label = "contact split factor",
- },
- {
- .name = "azoteq,trim-x",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x56,
- [IQS7211E] = 0x49,
- },
- .reg_shift = 0,
- .reg_width = 8,
- .label = "horizontal trim width",
- },
- {
- .name = "azoteq,trim-x",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7211A] = 0x68,
- },
- .label = "horizontal trim width",
- },
- {
- .name = "azoteq,trim-y",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7210A] = 0x56,
- [IQS7211E] = 0x49,
- },
- .reg_shift = 8,
- .reg_width = 8,
- .label = "vertical trim height",
- },
- {
- .name = "azoteq,trim-y",
- .reg_addr[IQS7211_REG_GRP_SYS] = {
- [IQS7211A] = 0x69,
- },
- .label = "vertical trim height",
- },
- {
- .name = "azoteq,gesture-max-ms",
- .reg_key = IQS7211_REG_KEY_TAP,
- .reg_addr[IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x59,
- [IQS7211A] = 0x81,
- [IQS7211E] = 0x4C,
- },
- .label = "maximum gesture time",
- },
- {
- .name = "azoteq,gesture-mid-ms",
- .reg_key = IQS7211_REG_KEY_TAP,
- .reg_addr[IQS7211_REG_GRP_TP] = {
- [IQS7211E] = 0x4D,
- },
- .label = "repeated gesture time",
- },
- {
- .name = "azoteq,gesture-dist",
- .reg_key = IQS7211_REG_KEY_TAP,
- .reg_addr[IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x5A,
- [IQS7211A] = 0x82,
- [IQS7211E] = 0x4E,
- },
- .label = "gesture distance",
- },
- {
- .name = "azoteq,gesture-dist",
- .reg_key = IQS7211_REG_KEY_HOLD,
- .reg_addr[IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x5A,
- [IQS7211A] = 0x82,
- [IQS7211E] = 0x4E,
- },
- .label = "gesture distance",
- },
- {
- .name = "azoteq,gesture-min-ms",
- .reg_key = IQS7211_REG_KEY_HOLD,
- .reg_addr[IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x5B,
- [IQS7211A] = 0x83,
- [IQS7211E] = 0x4F,
- },
- .label = "minimum gesture time",
- },
- {
- .name = "azoteq,gesture-max-ms",
- .reg_key = IQS7211_REG_KEY_AXIAL_X,
- .reg_addr[IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x5C,
- [IQS7211A] = 0x84,
- [IQS7211E] = 0x50,
- },
- .label = "maximum gesture time",
- },
- {
- .name = "azoteq,gesture-max-ms",
- .reg_key = IQS7211_REG_KEY_AXIAL_Y,
- .reg_addr[IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x5C,
- [IQS7211A] = 0x84,
- [IQS7211E] = 0x50,
- },
- .label = "maximum gesture time",
- },
- {
- .name = "azoteq,gesture-dist",
- .reg_key = IQS7211_REG_KEY_AXIAL_X,
- .reg_addr[IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x5D,
- [IQS7211A] = 0x85,
- [IQS7211E] = 0x51,
- },
- .label = "gesture distance",
- },
- {
- .name = "azoteq,gesture-dist",
- .reg_key = IQS7211_REG_KEY_AXIAL_Y,
- .reg_addr[IQS7211_REG_GRP_TP] = {
- [IQS7210A] = 0x5E,
- [IQS7211A] = 0x86,
- [IQS7211E] = 0x52,
- },
- .label = "gesture distance",
- },
- {
- .name = "azoteq,gesture-dist-rep",
- .reg_key = IQS7211_REG_KEY_AXIAL_X,
- .reg_addr[IQS7211_REG_GRP_TP] = {
- [IQS7211E] = 0x53,
- },
- .label = "repeated gesture distance",
- },
- {
- .name = "azoteq,gesture-dist-rep",
- .reg_key = IQS7211_REG_KEY_AXIAL_Y,
- .reg_addr[IQS7211_REG_GRP_TP] = {
- [IQS7211E] = 0x54,
- },
- .label = "repeated gesture distance",
- },
- {
- .name = "azoteq,thresh",
- .reg_key = IQS7211_REG_KEY_PALM,
- .reg_addr[IQS7211_REG_GRP_TP] = {
- [IQS7211E] = 0x55,
- },
- .reg_shift = 8,
- .reg_width = 8,
- .val_max = 42,
- .label = "threshold",
- },
- };
- static const u8 iqs7211_gesture_angle[] = {
- 0x00, 0x01, 0x02, 0x03,
- 0x04, 0x06, 0x07, 0x08,
- 0x09, 0x0A, 0x0B, 0x0C,
- 0x0E, 0x0F, 0x10, 0x11,
- 0x12, 0x14, 0x15, 0x16,
- 0x17, 0x19, 0x1A, 0x1B,
- 0x1C, 0x1E, 0x1F, 0x21,
- 0x22, 0x23, 0x25, 0x26,
- 0x28, 0x2A, 0x2B, 0x2D,
- 0x2E, 0x30, 0x32, 0x34,
- 0x36, 0x38, 0x3A, 0x3C,
- 0x3E, 0x40, 0x42, 0x45,
- 0x47, 0x4A, 0x4C, 0x4F,
- 0x52, 0x55, 0x58, 0x5B,
- 0x5F, 0x63, 0x66, 0x6B,
- 0x6F, 0x73, 0x78, 0x7E,
- 0x83, 0x89, 0x90, 0x97,
- 0x9E, 0xA7, 0xB0, 0xBA,
- 0xC5, 0xD1, 0xDF, 0xEF,
- };
- struct iqs7211_ver_info {
- __le16 prod_num;
- __le16 major;
- __le16 minor;
- __le32 patch;
- } __packed;
- struct iqs7211_touch_data {
- __le16 abs_x;
- __le16 abs_y;
- __le16 pressure;
- __le16 area;
- } __packed;
- struct iqs7211_tp_config {
- u8 tp_settings;
- u8 total_rx;
- u8 total_tx;
- u8 num_contacts;
- __le16 max_x;
- __le16 max_y;
- } __packed;
- struct iqs7211_private {
- const struct iqs7211_dev_desc *dev_desc;
- struct gpio_desc *reset_gpio;
- struct gpio_desc *irq_gpio;
- struct i2c_client *client;
- struct input_dev *tp_idev;
- struct input_dev *kp_idev;
- struct iqs7211_ver_info ver_info;
- struct iqs7211_tp_config tp_config;
- struct touchscreen_properties prop;
- struct list_head reg_field_head;
- enum iqs7211_comms_mode comms_init;
- enum iqs7211_comms_mode comms_mode;
- unsigned int num_contacts;
- unsigned int kp_code[ARRAY_SIZE(iqs7211e_kp_events)];
- u8 rx_tx_map[IQS7211_MAX_CTX + 1];
- u8 cycle_alloc[2][33];
- u8 exp_file[2];
- u16 event_mask;
- u16 ati_start;
- u16 gesture_cache;
- };
- static int iqs7211_irq_poll(struct iqs7211_private *iqs7211, u64 timeout_us)
- {
- int error, val;
- error = readx_poll_timeout(gpiod_get_value_cansleep, iqs7211->irq_gpio,
- val, val, IQS7211_COMMS_SLEEP_US, timeout_us);
- return val < 0 ? val : error;
- }
- static int iqs7211_hard_reset(struct iqs7211_private *iqs7211)
- {
- if (!iqs7211->reset_gpio)
- return 0;
- gpiod_set_value_cansleep(iqs7211->reset_gpio, 1);
- /*
- * The following delay ensures the shared RDY/MCLR pin is sampled in
- * between periodic assertions by the device and assumes the default
- * communication timeout has not been overwritten in OTP memory.
- */
- if (iqs7211->reset_gpio == iqs7211->irq_gpio)
- msleep(IQS7211_RESET_TIMEOUT_MS);
- else
- usleep_range(1000, 1100);
- gpiod_set_value_cansleep(iqs7211->reset_gpio, 0);
- if (iqs7211->reset_gpio == iqs7211->irq_gpio)
- iqs7211_irq_wait();
- return iqs7211_irq_poll(iqs7211, IQS7211_START_TIMEOUT_US);
- }
- static int iqs7211_force_comms(struct iqs7211_private *iqs7211)
- {
- u8 msg_buf[] = { 0xFF, };
- int ret;
- switch (iqs7211->comms_mode) {
- case IQS7211_COMMS_MODE_WAIT:
- return iqs7211_irq_poll(iqs7211, IQS7211_START_TIMEOUT_US);
- case IQS7211_COMMS_MODE_FREE:
- return 0;
- case IQS7211_COMMS_MODE_FORCE:
- break;
- default:
- return -EINVAL;
- }
- /*
- * The device cannot communicate until it asserts its interrupt (RDY)
- * pin. Attempts to do so while RDY is deasserted return an ACK; how-
- * ever all write data is ignored, and all read data returns 0xEE.
- *
- * Unsolicited communication must be preceded by a special force com-
- * munication command, after which the device eventually asserts its
- * RDY pin and agrees to communicate.
- *
- * Regardless of whether communication is forced or the result of an
- * interrupt, the device automatically deasserts its RDY pin once it
- * detects an I2C stop condition, or a timeout expires.
- */
- ret = gpiod_get_value_cansleep(iqs7211->irq_gpio);
- if (ret < 0)
- return ret;
- else if (ret > 0)
- return 0;
- ret = i2c_master_send(iqs7211->client, msg_buf, sizeof(msg_buf));
- if (ret < (int)sizeof(msg_buf)) {
- if (ret >= 0)
- ret = -EIO;
- msleep(IQS7211_COMMS_RETRY_MS);
- return ret;
- }
- iqs7211_irq_wait();
- return iqs7211_irq_poll(iqs7211, IQS7211_COMMS_TIMEOUT_US);
- }
- static int iqs7211_read_burst(struct iqs7211_private *iqs7211,
- u8 reg, void *val, u16 val_len)
- {
- int ret, i;
- struct i2c_client *client = iqs7211->client;
- struct i2c_msg msg[] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = sizeof(reg),
- .buf = ®,
- },
- {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = val_len,
- .buf = (u8 *)val,
- },
- };
- /*
- * The following loop protects against an edge case in which the RDY
- * pin is automatically deasserted just as the read is initiated. In
- * that case, the read must be retried using forced communication.
- */
- for (i = 0; i < IQS7211_NUM_RETRIES; i++) {
- ret = iqs7211_force_comms(iqs7211);
- if (ret < 0)
- continue;
- ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
- if (ret < (int)ARRAY_SIZE(msg)) {
- if (ret >= 0)
- ret = -EIO;
- msleep(IQS7211_COMMS_RETRY_MS);
- continue;
- }
- if (get_unaligned_le16(msg[1].buf) == IQS7211_COMMS_ERROR) {
- ret = -ENODATA;
- continue;
- }
- ret = 0;
- break;
- }
- iqs7211_irq_wait();
- if (ret < 0)
- dev_err(&client->dev,
- "Failed to read from address 0x%02X: %d\n", reg, ret);
- return ret;
- }
- static int iqs7211_read_word(struct iqs7211_private *iqs7211, u8 reg, u16 *val)
- {
- __le16 val_buf;
- int error;
- error = iqs7211_read_burst(iqs7211, reg, &val_buf, sizeof(val_buf));
- if (error)
- return error;
- *val = le16_to_cpu(val_buf);
- return 0;
- }
- static int iqs7211_write_burst(struct iqs7211_private *iqs7211,
- u8 reg, const void *val, u16 val_len)
- {
- int msg_len = sizeof(reg) + val_len;
- int ret, i;
- struct i2c_client *client = iqs7211->client;
- u8 *msg_buf;
- msg_buf = kzalloc(msg_len, GFP_KERNEL);
- if (!msg_buf)
- return -ENOMEM;
- *msg_buf = reg;
- memcpy(msg_buf + sizeof(reg), val, val_len);
- /*
- * The following loop protects against an edge case in which the RDY
- * pin is automatically asserted just before the force communication
- * command is sent.
- *
- * In that case, the subsequent I2C stop condition tricks the device
- * into preemptively deasserting the RDY pin and the command must be
- * sent again.
- */
- for (i = 0; i < IQS7211_NUM_RETRIES; i++) {
- ret = iqs7211_force_comms(iqs7211);
- if (ret < 0)
- continue;
- ret = i2c_master_send(client, msg_buf, msg_len);
- if (ret < msg_len) {
- if (ret >= 0)
- ret = -EIO;
- msleep(IQS7211_COMMS_RETRY_MS);
- continue;
- }
- ret = 0;
- break;
- }
- kfree(msg_buf);
- iqs7211_irq_wait();
- if (ret < 0)
- dev_err(&client->dev,
- "Failed to write to address 0x%02X: %d\n", reg, ret);
- return ret;
- }
- static int iqs7211_write_word(struct iqs7211_private *iqs7211, u8 reg, u16 val)
- {
- __le16 val_buf = cpu_to_le16(val);
- return iqs7211_write_burst(iqs7211, reg, &val_buf, sizeof(val_buf));
- }
- static int iqs7211_start_comms(struct iqs7211_private *iqs7211)
- {
- const struct iqs7211_dev_desc *dev_desc = iqs7211->dev_desc;
- struct i2c_client *client = iqs7211->client;
- bool forced_comms;
- unsigned int val;
- u16 comms_setup;
- int error;
- /*
- * Until forced communication can be enabled, the host must wait for a
- * communication window each time it intends to elicit a response from
- * the device.
- *
- * Forced communication is not necessary, however, if the host adapter
- * can support clock stretching. In that case, the device freely clock
- * stretches until all pending conversions are complete.
- */
- forced_comms = device_property_present(&client->dev,
- "azoteq,forced-comms");
- error = device_property_read_u32(&client->dev,
- "azoteq,forced-comms-default", &val);
- if (error == -EINVAL) {
- iqs7211->comms_init = IQS7211_COMMS_MODE_WAIT;
- } else if (error) {
- dev_err(&client->dev,
- "Failed to read default communication mode: %d\n",
- error);
- return error;
- } else if (val) {
- iqs7211->comms_init = forced_comms ? IQS7211_COMMS_MODE_FORCE
- : IQS7211_COMMS_MODE_WAIT;
- } else {
- iqs7211->comms_init = forced_comms ? IQS7211_COMMS_MODE_WAIT
- : IQS7211_COMMS_MODE_FREE;
- }
- iqs7211->comms_mode = iqs7211->comms_init;
- error = iqs7211_hard_reset(iqs7211);
- if (error) {
- dev_err(&client->dev, "Failed to reset device: %d\n", error);
- return error;
- }
- error = iqs7211_read_burst(iqs7211, IQS7211_PROD_NUM,
- &iqs7211->ver_info,
- sizeof(iqs7211->ver_info));
- if (error)
- return error;
- if (le16_to_cpu(iqs7211->ver_info.prod_num) != dev_desc->prod_num) {
- dev_err(&client->dev, "Invalid product number: %u\n",
- le16_to_cpu(iqs7211->ver_info.prod_num));
- return -EINVAL;
- }
- error = iqs7211_read_word(iqs7211, dev_desc->sys_ctrl + 1,
- &comms_setup);
- if (error)
- return error;
- if (forced_comms)
- comms_setup |= dev_desc->comms_req;
- else
- comms_setup &= ~dev_desc->comms_req;
- error = iqs7211_write_word(iqs7211, dev_desc->sys_ctrl + 1,
- comms_setup | dev_desc->comms_end);
- if (error)
- return error;
- if (forced_comms)
- iqs7211->comms_mode = IQS7211_COMMS_MODE_FORCE;
- else
- iqs7211->comms_mode = IQS7211_COMMS_MODE_FREE;
- error = iqs7211_read_burst(iqs7211, dev_desc->exp_file,
- iqs7211->exp_file,
- sizeof(iqs7211->exp_file));
- if (error)
- return error;
- error = iqs7211_read_burst(iqs7211, dev_desc->tp_config,
- &iqs7211->tp_config,
- sizeof(iqs7211->tp_config));
- if (error)
- return error;
- error = iqs7211_write_word(iqs7211, dev_desc->sys_ctrl + 1,
- comms_setup);
- if (error)
- return error;
- iqs7211->event_mask = comms_setup & ~IQS7211_EVENT_MASK_ALL;
- iqs7211->event_mask |= (IQS7211_EVENT_MASK_ATI | IQS7211_EVENT_MODE);
- return 0;
- }
- static int iqs7211_init_device(struct iqs7211_private *iqs7211)
- {
- const struct iqs7211_dev_desc *dev_desc = iqs7211->dev_desc;
- struct iqs7211_reg_field_desc *reg_field;
- __le16 sys_ctrl[] = {
- cpu_to_le16(dev_desc->ack_reset),
- cpu_to_le16(iqs7211->event_mask),
- };
- int error, i;
- /*
- * Acknowledge reset before writing any registers in case the device
- * suffers a spurious reset during initialization. The communication
- * mode is configured at this time as well.
- */
- error = iqs7211_write_burst(iqs7211, dev_desc->sys_ctrl, sys_ctrl,
- sizeof(sys_ctrl));
- if (error)
- return error;
- if (iqs7211->event_mask & dev_desc->comms_req)
- iqs7211->comms_mode = IQS7211_COMMS_MODE_FORCE;
- else
- iqs7211->comms_mode = IQS7211_COMMS_MODE_FREE;
- /*
- * Take advantage of the stop-bit disable function, if available, to
- * save the trouble of having to reopen a communication window after
- * each read or write.
- */
- error = iqs7211_write_word(iqs7211, dev_desc->sys_ctrl + 1,
- iqs7211->event_mask | dev_desc->comms_end);
- if (error)
- return error;
- list_for_each_entry(reg_field, &iqs7211->reg_field_head, list) {
- u16 new_val = reg_field->val;
- if (reg_field->mask < U16_MAX) {
- u16 old_val;
- error = iqs7211_read_word(iqs7211, reg_field->addr,
- &old_val);
- if (error)
- return error;
- new_val = old_val & ~reg_field->mask;
- new_val |= reg_field->val;
- if (new_val == old_val)
- continue;
- }
- error = iqs7211_write_word(iqs7211, reg_field->addr, new_val);
- if (error)
- return error;
- }
- error = iqs7211_write_burst(iqs7211, dev_desc->tp_config,
- &iqs7211->tp_config,
- sizeof(iqs7211->tp_config));
- if (error)
- return error;
- if (**iqs7211->cycle_alloc) {
- error = iqs7211_write_burst(iqs7211, dev_desc->rx_tx_map,
- &iqs7211->rx_tx_map,
- dev_desc->num_ctx);
- if (error)
- return error;
- for (i = 0; i < sizeof(dev_desc->cycle_limit); i++) {
- error = iqs7211_write_burst(iqs7211,
- dev_desc->cycle_alloc[i],
- iqs7211->cycle_alloc[i],
- dev_desc->cycle_limit[i] * 3);
- if (error)
- return error;
- }
- }
- *sys_ctrl = cpu_to_le16(iqs7211->ati_start);
- return iqs7211_write_burst(iqs7211, dev_desc->sys_ctrl, sys_ctrl,
- sizeof(sys_ctrl));
- }
- static int iqs7211_add_field(struct iqs7211_private *iqs7211,
- struct iqs7211_reg_field_desc new_field)
- {
- struct i2c_client *client = iqs7211->client;
- struct iqs7211_reg_field_desc *reg_field;
- if (!new_field.addr)
- return 0;
- list_for_each_entry(reg_field, &iqs7211->reg_field_head, list) {
- if (reg_field->addr != new_field.addr)
- continue;
- reg_field->mask |= new_field.mask;
- reg_field->val |= new_field.val;
- return 0;
- }
- reg_field = devm_kzalloc(&client->dev, sizeof(*reg_field), GFP_KERNEL);
- if (!reg_field)
- return -ENOMEM;
- reg_field->addr = new_field.addr;
- reg_field->mask = new_field.mask;
- reg_field->val = new_field.val;
- list_add(®_field->list, &iqs7211->reg_field_head);
- return 0;
- }
- static int iqs7211_parse_props(struct iqs7211_private *iqs7211,
- struct fwnode_handle *reg_grp_node,
- enum iqs7211_reg_grp_id reg_grp,
- enum iqs7211_reg_key_id reg_key)
- {
- struct i2c_client *client = iqs7211->client;
- int i;
- for (i = 0; i < ARRAY_SIZE(iqs7211_props); i++) {
- const char *name = iqs7211_props[i].name;
- u8 reg_addr = iqs7211_props[i].reg_addr[reg_grp]
- [iqs7211->dev_desc -
- iqs7211_devs];
- int reg_shift = iqs7211_props[i].reg_shift;
- int reg_width = iqs7211_props[i].reg_width ? : 16;
- int val_pitch = iqs7211_props[i].val_pitch ? : 1;
- int val_min = iqs7211_props[i].val_min;
- int val_max = iqs7211_props[i].val_max;
- const char *label = iqs7211_props[i].label ? : name;
- struct iqs7211_reg_field_desc reg_field;
- unsigned int val;
- int error;
- if (iqs7211_props[i].reg_key != reg_key)
- continue;
- if (!reg_addr)
- continue;
- error = fwnode_property_read_u32(reg_grp_node, name, &val);
- if (error == -EINVAL) {
- continue;
- } else if (error) {
- dev_err(&client->dev, "Failed to read %s %s: %d\n",
- fwnode_get_name(reg_grp_node), label, error);
- return error;
- }
- if (!val_max)
- val_max = GENMASK(reg_width - 1, 0) * val_pitch;
- if (val < val_min || val > val_max) {
- dev_err(&client->dev, "Invalid %s: %u\n", label, val);
- return -EINVAL;
- }
- reg_field.addr = reg_addr;
- reg_field.mask = GENMASK(reg_shift + reg_width - 1, reg_shift);
- reg_field.val = val / val_pitch << reg_shift;
- error = iqs7211_add_field(iqs7211, reg_field);
- if (error)
- return error;
- }
- return 0;
- }
- static int iqs7211_parse_event(struct iqs7211_private *iqs7211,
- struct fwnode_handle *event_node,
- enum iqs7211_reg_grp_id reg_grp,
- enum iqs7211_reg_key_id reg_key,
- unsigned int *event_code)
- {
- const struct iqs7211_dev_desc *dev_desc = iqs7211->dev_desc;
- struct i2c_client *client = iqs7211->client;
- struct iqs7211_reg_field_desc reg_field;
- unsigned int val;
- int error;
- error = iqs7211_parse_props(iqs7211, event_node, reg_grp, reg_key);
- if (error)
- return error;
- if (reg_key == IQS7211_REG_KEY_AXIAL_X ||
- reg_key == IQS7211_REG_KEY_AXIAL_Y) {
- error = fwnode_property_read_u32(event_node,
- "azoteq,gesture-angle", &val);
- if (!error) {
- if (val >= ARRAY_SIZE(iqs7211_gesture_angle)) {
- dev_err(&client->dev,
- "Invalid %s gesture angle: %u\n",
- fwnode_get_name(event_node), val);
- return -EINVAL;
- }
- reg_field.addr = dev_desc->gesture_angle;
- reg_field.mask = U8_MAX;
- reg_field.val = iqs7211_gesture_angle[val];
- error = iqs7211_add_field(iqs7211, reg_field);
- if (error)
- return error;
- } else if (error != -EINVAL) {
- dev_err(&client->dev,
- "Failed to read %s gesture angle: %d\n",
- fwnode_get_name(event_node), error);
- return error;
- }
- }
- error = fwnode_property_read_u32(event_node, "linux,code", event_code);
- if (error == -EINVAL)
- error = 0;
- else if (error)
- dev_err(&client->dev, "Failed to read %s code: %d\n",
- fwnode_get_name(event_node), error);
- return error;
- }
- static int iqs7211_parse_cycles(struct iqs7211_private *iqs7211,
- struct fwnode_handle *tp_node)
- {
- const struct iqs7211_dev_desc *dev_desc = iqs7211->dev_desc;
- struct i2c_client *client = iqs7211->client;
- int num_cycles = dev_desc->cycle_limit[0] + dev_desc->cycle_limit[1];
- int error, count, i, j, k, cycle_start;
- unsigned int cycle_alloc[IQS7211_MAX_CYCLES][2];
- u8 total_rx = iqs7211->tp_config.total_rx;
- u8 total_tx = iqs7211->tp_config.total_tx;
- for (i = 0; i < IQS7211_MAX_CYCLES * 2; i++)
- *(cycle_alloc[0] + i) = U8_MAX;
- count = fwnode_property_count_u32(tp_node, "azoteq,channel-select");
- if (count == -EINVAL) {
- /*
- * Assign each sensing cycle's slots (0 and 1) to a channel,
- * defined as the intersection between two CRx and CTx pins.
- * A channel assignment of 255 means the slot is unused.
- */
- for (i = 0, cycle_start = 0; i < total_tx; i++) {
- int cycle_stop = 0;
- for (j = 0; j < total_rx; j++) {
- /*
- * Channels formed by CRx0-3 and CRx4-7 are
- * bound to slots 0 and 1, respectively.
- */
- int slot = iqs7211->rx_tx_map[j] < 4 ? 0 : 1;
- int chan = i * total_rx + j;
- for (k = cycle_start; k < num_cycles; k++) {
- if (cycle_alloc[k][slot] < U8_MAX)
- continue;
- cycle_alloc[k][slot] = chan;
- break;
- }
- if (k < num_cycles) {
- cycle_stop = max(k, cycle_stop);
- continue;
- }
- dev_err(&client->dev,
- "Insufficient number of cycles\n");
- return -EINVAL;
- }
- /*
- * Sensing cycles cannot straddle more than one CTx
- * pin. As such, the next row's starting cycle must
- * be greater than the previous row's highest cycle.
- */
- cycle_start = cycle_stop + 1;
- }
- } else if (count < 0) {
- dev_err(&client->dev, "Failed to count channels: %d\n", count);
- return count;
- } else if (count > num_cycles * 2) {
- dev_err(&client->dev, "Insufficient number of cycles\n");
- return -EINVAL;
- } else if (count > 0) {
- error = fwnode_property_read_u32_array(tp_node,
- "azoteq,channel-select",
- cycle_alloc[0], count);
- if (error) {
- dev_err(&client->dev, "Failed to read channels: %d\n",
- error);
- return error;
- }
- for (i = 0; i < count; i++) {
- int chan = *(cycle_alloc[0] + i);
- if (chan == U8_MAX)
- continue;
- if (chan >= total_rx * total_tx) {
- dev_err(&client->dev, "Invalid channel: %d\n",
- chan);
- return -EINVAL;
- }
- for (j = 0; j < count; j++) {
- if (j == i || *(cycle_alloc[0] + j) != chan)
- continue;
- dev_err(&client->dev, "Duplicate channel: %d\n",
- chan);
- return -EINVAL;
- }
- }
- }
- /*
- * Once the raw channel assignments have been derived, they must be
- * packed according to the device's register map.
- */
- for (i = 0, cycle_start = 0; i < sizeof(dev_desc->cycle_limit); i++) {
- int offs = 0;
- for (j = cycle_start;
- j < cycle_start + dev_desc->cycle_limit[i]; j++) {
- iqs7211->cycle_alloc[i][offs++] = 0x05;
- iqs7211->cycle_alloc[i][offs++] = cycle_alloc[j][0];
- iqs7211->cycle_alloc[i][offs++] = cycle_alloc[j][1];
- }
- cycle_start += dev_desc->cycle_limit[i];
- }
- return 0;
- }
- static int iqs7211_parse_tp(struct iqs7211_private *iqs7211,
- struct fwnode_handle *tp_node)
- {
- const struct iqs7211_dev_desc *dev_desc = iqs7211->dev_desc;
- struct i2c_client *client = iqs7211->client;
- unsigned int pins[IQS7211_MAX_CTX];
- int error, count, i, j;
- count = fwnode_property_count_u32(tp_node, "azoteq,rx-enable");
- if (count == -EINVAL) {
- return 0;
- } else if (count < 0) {
- dev_err(&client->dev, "Failed to count CRx pins: %d\n", count);
- return count;
- } else if (count > IQS7211_NUM_CRX) {
- dev_err(&client->dev, "Invalid number of CRx pins\n");
- return -EINVAL;
- }
- error = fwnode_property_read_u32_array(tp_node, "azoteq,rx-enable",
- pins, count);
- if (error) {
- dev_err(&client->dev, "Failed to read CRx pins: %d\n", error);
- return error;
- }
- for (i = 0; i < count; i++) {
- if (pins[i] >= IQS7211_NUM_CRX) {
- dev_err(&client->dev, "Invalid CRx pin: %u\n", pins[i]);
- return -EINVAL;
- }
- iqs7211->rx_tx_map[i] = pins[i];
- }
- iqs7211->tp_config.total_rx = count;
- count = fwnode_property_count_u32(tp_node, "azoteq,tx-enable");
- if (count < 0) {
- dev_err(&client->dev, "Failed to count CTx pins: %d\n", count);
- return count;
- } else if (count > dev_desc->num_ctx) {
- dev_err(&client->dev, "Invalid number of CTx pins\n");
- return -EINVAL;
- }
- error = fwnode_property_read_u32_array(tp_node, "azoteq,tx-enable",
- pins, count);
- if (error) {
- dev_err(&client->dev, "Failed to read CTx pins: %d\n", error);
- return error;
- }
- for (i = 0; i < count; i++) {
- if (pins[i] >= dev_desc->num_ctx) {
- dev_err(&client->dev, "Invalid CTx pin: %u\n", pins[i]);
- return -EINVAL;
- }
- for (j = 0; j < iqs7211->tp_config.total_rx; j++) {
- if (iqs7211->rx_tx_map[j] != pins[i])
- continue;
- dev_err(&client->dev, "Conflicting CTx pin: %u\n",
- pins[i]);
- return -EINVAL;
- }
- iqs7211->rx_tx_map[iqs7211->tp_config.total_rx + i] = pins[i];
- }
- iqs7211->tp_config.total_tx = count;
- return iqs7211_parse_cycles(iqs7211, tp_node);
- }
- static int iqs7211_parse_alp(struct iqs7211_private *iqs7211,
- struct fwnode_handle *alp_node)
- {
- const struct iqs7211_dev_desc *dev_desc = iqs7211->dev_desc;
- struct i2c_client *client = iqs7211->client;
- struct iqs7211_reg_field_desc reg_field;
- int error, count, i;
- count = fwnode_property_count_u32(alp_node, "azoteq,rx-enable");
- if (count < 0 && count != -EINVAL) {
- dev_err(&client->dev, "Failed to count CRx pins: %d\n", count);
- return count;
- } else if (count > IQS7211_NUM_CRX) {
- dev_err(&client->dev, "Invalid number of CRx pins\n");
- return -EINVAL;
- } else if (count >= 0) {
- unsigned int pins[IQS7211_NUM_CRX];
- error = fwnode_property_read_u32_array(alp_node,
- "azoteq,rx-enable",
- pins, count);
- if (error) {
- dev_err(&client->dev, "Failed to read CRx pins: %d\n",
- error);
- return error;
- }
- reg_field.addr = dev_desc->alp_config;
- reg_field.mask = GENMASK(IQS7211_NUM_CRX - 1, 0);
- reg_field.val = 0;
- for (i = 0; i < count; i++) {
- if (pins[i] < dev_desc->min_crx_alp ||
- pins[i] >= IQS7211_NUM_CRX) {
- dev_err(&client->dev, "Invalid CRx pin: %u\n",
- pins[i]);
- return -EINVAL;
- }
- reg_field.val |= BIT(pins[i]);
- }
- error = iqs7211_add_field(iqs7211, reg_field);
- if (error)
- return error;
- }
- count = fwnode_property_count_u32(alp_node, "azoteq,tx-enable");
- if (count < 0 && count != -EINVAL) {
- dev_err(&client->dev, "Failed to count CTx pins: %d\n", count);
- return count;
- } else if (count > dev_desc->num_ctx) {
- dev_err(&client->dev, "Invalid number of CTx pins\n");
- return -EINVAL;
- } else if (count >= 0) {
- unsigned int pins[IQS7211_MAX_CTX];
- error = fwnode_property_read_u32_array(alp_node,
- "azoteq,tx-enable",
- pins, count);
- if (error) {
- dev_err(&client->dev, "Failed to read CTx pins: %d\n",
- error);
- return error;
- }
- reg_field.addr = dev_desc->alp_config + 1;
- reg_field.mask = GENMASK(dev_desc->num_ctx - 1, 0);
- reg_field.val = 0;
- for (i = 0; i < count; i++) {
- if (pins[i] >= dev_desc->num_ctx) {
- dev_err(&client->dev, "Invalid CTx pin: %u\n",
- pins[i]);
- return -EINVAL;
- }
- reg_field.val |= BIT(pins[i]);
- }
- error = iqs7211_add_field(iqs7211, reg_field);
- if (error)
- return error;
- }
- return 0;
- }
- static int (*iqs7211_parse_extra[IQS7211_NUM_REG_GRPS])
- (struct iqs7211_private *iqs7211,
- struct fwnode_handle *reg_grp_node) = {
- [IQS7211_REG_GRP_TP] = iqs7211_parse_tp,
- [IQS7211_REG_GRP_ALP] = iqs7211_parse_alp,
- };
- static int iqs7211_parse_reg_grp(struct iqs7211_private *iqs7211,
- struct fwnode_handle *reg_grp_node,
- enum iqs7211_reg_grp_id reg_grp)
- {
- const struct iqs7211_dev_desc *dev_desc = iqs7211->dev_desc;
- struct iqs7211_reg_field_desc reg_field;
- int error, i;
- error = iqs7211_parse_props(iqs7211, reg_grp_node, reg_grp,
- IQS7211_REG_KEY_NONE);
- if (error)
- return error;
- if (iqs7211_parse_extra[reg_grp]) {
- error = iqs7211_parse_extra[reg_grp](iqs7211, reg_grp_node);
- if (error)
- return error;
- }
- iqs7211->ati_start |= dev_desc->ati_start[reg_grp];
- reg_field.addr = dev_desc->kp_enable[reg_grp];
- reg_field.mask = 0;
- reg_field.val = 0;
- for (i = 0; i < dev_desc->num_kp_events; i++) {
- const char *event_name = dev_desc->kp_events[i].name;
- struct fwnode_handle *event_node;
- if (dev_desc->kp_events[i].reg_grp != reg_grp)
- continue;
- reg_field.mask |= dev_desc->kp_events[i].enable;
- if (event_name)
- event_node = fwnode_get_named_child_node(reg_grp_node,
- event_name);
- else
- event_node = fwnode_handle_get(reg_grp_node);
- if (!event_node)
- continue;
- error = iqs7211_parse_event(iqs7211, event_node,
- dev_desc->kp_events[i].reg_grp,
- dev_desc->kp_events[i].reg_key,
- &iqs7211->kp_code[i]);
- fwnode_handle_put(event_node);
- if (error)
- return error;
- reg_field.val |= dev_desc->kp_events[i].enable;
- iqs7211->event_mask |= iqs7211_reg_grp_masks[reg_grp];
- }
- return iqs7211_add_field(iqs7211, reg_field);
- }
- static int iqs7211_register_kp(struct iqs7211_private *iqs7211)
- {
- const struct iqs7211_dev_desc *dev_desc = iqs7211->dev_desc;
- struct input_dev *kp_idev = iqs7211->kp_idev;
- struct i2c_client *client = iqs7211->client;
- int error, i;
- for (i = 0; i < dev_desc->num_kp_events; i++)
- if (iqs7211->kp_code[i])
- break;
- if (i == dev_desc->num_kp_events)
- return 0;
- kp_idev = devm_input_allocate_device(&client->dev);
- if (!kp_idev)
- return -ENOMEM;
- iqs7211->kp_idev = kp_idev;
- kp_idev->name = dev_desc->kp_name;
- kp_idev->id.bustype = BUS_I2C;
- for (i = 0; i < dev_desc->num_kp_events; i++)
- if (iqs7211->kp_code[i])
- input_set_capability(iqs7211->kp_idev, EV_KEY,
- iqs7211->kp_code[i]);
- error = input_register_device(kp_idev);
- if (error)
- dev_err(&client->dev, "Failed to register %s: %d\n",
- kp_idev->name, error);
- return error;
- }
- static int iqs7211_register_tp(struct iqs7211_private *iqs7211)
- {
- const struct iqs7211_dev_desc *dev_desc = iqs7211->dev_desc;
- struct touchscreen_properties *prop = &iqs7211->prop;
- struct input_dev *tp_idev = iqs7211->tp_idev;
- struct i2c_client *client = iqs7211->client;
- int error;
- error = device_property_read_u32(&client->dev, "azoteq,num-contacts",
- &iqs7211->num_contacts);
- if (error == -EINVAL) {
- return 0;
- } else if (error) {
- dev_err(&client->dev, "Failed to read number of contacts: %d\n",
- error);
- return error;
- } else if (iqs7211->num_contacts > IQS7211_MAX_CONTACTS) {
- dev_err(&client->dev, "Invalid number of contacts: %u\n",
- iqs7211->num_contacts);
- return -EINVAL;
- }
- iqs7211->tp_config.num_contacts = iqs7211->num_contacts ? : 1;
- if (!iqs7211->num_contacts)
- return 0;
- iqs7211->event_mask |= IQS7211_EVENT_MASK_MOVE;
- tp_idev = devm_input_allocate_device(&client->dev);
- if (!tp_idev)
- return -ENOMEM;
- iqs7211->tp_idev = tp_idev;
- tp_idev->name = dev_desc->tp_name;
- tp_idev->id.bustype = BUS_I2C;
- input_set_abs_params(tp_idev, ABS_MT_POSITION_X,
- 0, le16_to_cpu(iqs7211->tp_config.max_x), 0, 0);
- input_set_abs_params(tp_idev, ABS_MT_POSITION_Y,
- 0, le16_to_cpu(iqs7211->tp_config.max_y), 0, 0);
- input_set_abs_params(tp_idev, ABS_MT_PRESSURE, 0, U16_MAX, 0, 0);
- touchscreen_parse_properties(tp_idev, true, prop);
- /*
- * The device reserves 0xFFFF for coordinates that correspond to slots
- * which are not in a state of touch.
- */
- if (prop->max_x >= U16_MAX || prop->max_y >= U16_MAX) {
- dev_err(&client->dev, "Invalid trackpad size: %u*%u\n",
- prop->max_x, prop->max_y);
- return -EINVAL;
- }
- iqs7211->tp_config.max_x = cpu_to_le16(prop->max_x);
- iqs7211->tp_config.max_y = cpu_to_le16(prop->max_y);
- error = input_mt_init_slots(tp_idev, iqs7211->num_contacts,
- INPUT_MT_DIRECT);
- if (error) {
- dev_err(&client->dev, "Failed to initialize slots: %d\n",
- error);
- return error;
- }
- error = input_register_device(tp_idev);
- if (error)
- dev_err(&client->dev, "Failed to register %s: %d\n",
- tp_idev->name, error);
- return error;
- }
- static int iqs7211_report(struct iqs7211_private *iqs7211)
- {
- const struct iqs7211_dev_desc *dev_desc = iqs7211->dev_desc;
- struct i2c_client *client = iqs7211->client;
- struct iqs7211_touch_data *touch_data;
- u16 info_flags, charge_mode, gesture_flags;
- __le16 status[12];
- int error, i;
- error = iqs7211_read_burst(iqs7211, dev_desc->sys_stat, status,
- dev_desc->contact_offs * sizeof(__le16) +
- iqs7211->num_contacts * sizeof(*touch_data));
- if (error)
- return error;
- info_flags = le16_to_cpu(status[dev_desc->info_offs]);
- if (info_flags & dev_desc->show_reset) {
- dev_err(&client->dev, "Unexpected device reset\n");
- /*
- * The device may or may not expect forced communication after
- * it exits hardware reset, so the corresponding state machine
- * must be reset as well.
- */
- iqs7211->comms_mode = iqs7211->comms_init;
- return iqs7211_init_device(iqs7211);
- }
- for (i = 0; i < ARRAY_SIZE(dev_desc->ati_error); i++) {
- if (!(info_flags & dev_desc->ati_error[i]))
- continue;
- dev_err(&client->dev, "Unexpected %s ATI error\n",
- iqs7211_reg_grp_names[i]);
- return 0;
- }
- for (i = 0; i < iqs7211->num_contacts; i++) {
- u16 pressure;
- touch_data = (struct iqs7211_touch_data *)
- &status[dev_desc->contact_offs] + i;
- pressure = le16_to_cpu(touch_data->pressure);
- input_mt_slot(iqs7211->tp_idev, i);
- if (input_mt_report_slot_state(iqs7211->tp_idev, MT_TOOL_FINGER,
- pressure != 0)) {
- touchscreen_report_pos(iqs7211->tp_idev, &iqs7211->prop,
- le16_to_cpu(touch_data->abs_x),
- le16_to_cpu(touch_data->abs_y),
- true);
- input_report_abs(iqs7211->tp_idev, ABS_MT_PRESSURE,
- pressure);
- }
- }
- if (iqs7211->num_contacts) {
- input_mt_sync_frame(iqs7211->tp_idev);
- input_sync(iqs7211->tp_idev);
- }
- if (!iqs7211->kp_idev)
- return 0;
- charge_mode = info_flags & GENMASK(dev_desc->charge_shift + 2,
- dev_desc->charge_shift);
- charge_mode >>= dev_desc->charge_shift;
- /*
- * A charging mode higher than 2 (idle mode) indicates the device last
- * operated in low-power mode and intends to express an ALP event.
- */
- if (info_flags & dev_desc->kp_events->mask && charge_mode > 2) {
- input_report_key(iqs7211->kp_idev, *iqs7211->kp_code, 1);
- input_sync(iqs7211->kp_idev);
- input_report_key(iqs7211->kp_idev, *iqs7211->kp_code, 0);
- }
- for (i = 0; i < dev_desc->num_kp_events; i++) {
- if (dev_desc->kp_events[i].reg_grp != IQS7211_REG_GRP_BTN)
- continue;
- input_report_key(iqs7211->kp_idev, iqs7211->kp_code[i],
- info_flags & dev_desc->kp_events[i].mask);
- }
- gesture_flags = le16_to_cpu(status[dev_desc->gesture_offs]);
- for (i = 0; i < dev_desc->num_kp_events; i++) {
- enum iqs7211_reg_key_id reg_key = dev_desc->kp_events[i].reg_key;
- u16 mask = dev_desc->kp_events[i].mask;
- if (dev_desc->kp_events[i].reg_grp != IQS7211_REG_GRP_TP)
- continue;
- if ((gesture_flags ^ iqs7211->gesture_cache) & mask)
- input_report_key(iqs7211->kp_idev, iqs7211->kp_code[i],
- gesture_flags & mask);
- iqs7211->gesture_cache &= ~mask;
- /*
- * Hold and palm gestures persist while the contact remains in
- * place; all others are momentary and hence are followed by a
- * complementary release event.
- */
- if (reg_key == IQS7211_REG_KEY_HOLD ||
- reg_key == IQS7211_REG_KEY_PALM) {
- iqs7211->gesture_cache |= gesture_flags & mask;
- gesture_flags &= ~mask;
- }
- }
- if (gesture_flags) {
- input_sync(iqs7211->kp_idev);
- for (i = 0; i < dev_desc->num_kp_events; i++)
- if (dev_desc->kp_events[i].reg_grp == IQS7211_REG_GRP_TP &&
- gesture_flags & dev_desc->kp_events[i].mask)
- input_report_key(iqs7211->kp_idev,
- iqs7211->kp_code[i], 0);
- }
- input_sync(iqs7211->kp_idev);
- return 0;
- }
- static irqreturn_t iqs7211_irq(int irq, void *context)
- {
- struct iqs7211_private *iqs7211 = context;
- return iqs7211_report(iqs7211) ? IRQ_NONE : IRQ_HANDLED;
- }
- static int iqs7211_suspend(struct device *dev)
- {
- struct iqs7211_private *iqs7211 = dev_get_drvdata(dev);
- const struct iqs7211_dev_desc *dev_desc = iqs7211->dev_desc;
- int error;
- if (!dev_desc->suspend || device_may_wakeup(dev))
- return 0;
- /*
- * I2C communication prompts the device to assert its RDY pin if it is
- * not already asserted. As such, the interrupt must be disabled so as
- * to prevent reentrant interrupts.
- */
- disable_irq(gpiod_to_irq(iqs7211->irq_gpio));
- error = iqs7211_write_word(iqs7211, dev_desc->sys_ctrl,
- dev_desc->suspend);
- enable_irq(gpiod_to_irq(iqs7211->irq_gpio));
- return error;
- }
- static int iqs7211_resume(struct device *dev)
- {
- struct iqs7211_private *iqs7211 = dev_get_drvdata(dev);
- const struct iqs7211_dev_desc *dev_desc = iqs7211->dev_desc;
- __le16 sys_ctrl[] = {
- 0,
- cpu_to_le16(iqs7211->event_mask),
- };
- int error;
- if (!dev_desc->suspend || device_may_wakeup(dev))
- return 0;
- disable_irq(gpiod_to_irq(iqs7211->irq_gpio));
- /*
- * Forced communication, if in use, must be explicitly enabled as part
- * of the wake-up command.
- */
- error = iqs7211_write_burst(iqs7211, dev_desc->sys_ctrl, sys_ctrl,
- sizeof(sys_ctrl));
- enable_irq(gpiod_to_irq(iqs7211->irq_gpio));
- return error;
- }
- static DEFINE_SIMPLE_DEV_PM_OPS(iqs7211_pm, iqs7211_suspend, iqs7211_resume);
- static ssize_t fw_info_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct iqs7211_private *iqs7211 = dev_get_drvdata(dev);
- return sysfs_emit(buf, "%u.%u.%u.%u:%u.%u\n",
- le16_to_cpu(iqs7211->ver_info.prod_num),
- le32_to_cpu(iqs7211->ver_info.patch),
- le16_to_cpu(iqs7211->ver_info.major),
- le16_to_cpu(iqs7211->ver_info.minor),
- iqs7211->exp_file[1], iqs7211->exp_file[0]);
- }
- static DEVICE_ATTR_RO(fw_info);
- static struct attribute *iqs7211_attrs[] = {
- &dev_attr_fw_info.attr,
- NULL
- };
- ATTRIBUTE_GROUPS(iqs7211);
- static const struct of_device_id iqs7211_of_match[] = {
- {
- .compatible = "azoteq,iqs7210a",
- .data = &iqs7211_devs[IQS7210A],
- },
- {
- .compatible = "azoteq,iqs7211a",
- .data = &iqs7211_devs[IQS7211A],
- },
- {
- .compatible = "azoteq,iqs7211e",
- .data = &iqs7211_devs[IQS7211E],
- },
- { }
- };
- MODULE_DEVICE_TABLE(of, iqs7211_of_match);
- static int iqs7211_probe(struct i2c_client *client)
- {
- struct iqs7211_private *iqs7211;
- enum iqs7211_reg_grp_id reg_grp;
- unsigned long irq_flags;
- bool shared_irq;
- int error, irq;
- iqs7211 = devm_kzalloc(&client->dev, sizeof(*iqs7211), GFP_KERNEL);
- if (!iqs7211)
- return -ENOMEM;
- i2c_set_clientdata(client, iqs7211);
- iqs7211->client = client;
- INIT_LIST_HEAD(&iqs7211->reg_field_head);
- iqs7211->dev_desc = device_get_match_data(&client->dev);
- if (!iqs7211->dev_desc)
- return -ENODEV;
- shared_irq = iqs7211->dev_desc->num_ctx == IQS7211_MAX_CTX;
- /*
- * The RDY pin behaves as an interrupt, but must also be polled ahead
- * of unsolicited I2C communication. As such, it is first opened as a
- * GPIO and then passed to gpiod_to_irq() to register the interrupt.
- *
- * If an extra CTx pin is present, the RDY and MCLR pins are combined
- * into a single bidirectional pin. In that case, the platform's GPIO
- * must be configured as an open-drain output.
- */
- iqs7211->irq_gpio = devm_gpiod_get(&client->dev, "irq",
- shared_irq ? GPIOD_OUT_LOW
- : GPIOD_IN);
- if (IS_ERR(iqs7211->irq_gpio)) {
- error = PTR_ERR(iqs7211->irq_gpio);
- dev_err(&client->dev, "Failed to request IRQ GPIO: %d\n",
- error);
- return error;
- }
- if (shared_irq) {
- iqs7211->reset_gpio = iqs7211->irq_gpio;
- } else {
- iqs7211->reset_gpio = devm_gpiod_get_optional(&client->dev,
- "reset",
- GPIOD_OUT_HIGH);
- if (IS_ERR(iqs7211->reset_gpio)) {
- error = PTR_ERR(iqs7211->reset_gpio);
- dev_err(&client->dev,
- "Failed to request reset GPIO: %d\n", error);
- return error;
- }
- }
- error = iqs7211_start_comms(iqs7211);
- if (error)
- return error;
- for (reg_grp = 0; reg_grp < IQS7211_NUM_REG_GRPS; reg_grp++) {
- const char *reg_grp_name = iqs7211_reg_grp_names[reg_grp];
- struct fwnode_handle *reg_grp_node;
- if (reg_grp_name)
- reg_grp_node = device_get_named_child_node(&client->dev,
- reg_grp_name);
- else
- reg_grp_node = fwnode_handle_get(dev_fwnode(&client->dev));
- if (!reg_grp_node)
- continue;
- error = iqs7211_parse_reg_grp(iqs7211, reg_grp_node, reg_grp);
- fwnode_handle_put(reg_grp_node);
- if (error)
- return error;
- }
- error = iqs7211_register_kp(iqs7211);
- if (error)
- return error;
- error = iqs7211_register_tp(iqs7211);
- if (error)
- return error;
- error = iqs7211_init_device(iqs7211);
- if (error)
- return error;
- irq = gpiod_to_irq(iqs7211->irq_gpio);
- if (irq < 0)
- return irq;
- irq_flags = gpiod_is_active_low(iqs7211->irq_gpio) ? IRQF_TRIGGER_LOW
- : IRQF_TRIGGER_HIGH;
- irq_flags |= IRQF_ONESHOT;
- error = devm_request_threaded_irq(&client->dev, irq, NULL, iqs7211_irq,
- irq_flags, client->name, iqs7211);
- if (error)
- dev_err(&client->dev, "Failed to request IRQ: %d\n", error);
- return error;
- }
- static struct i2c_driver iqs7211_i2c_driver = {
- .probe = iqs7211_probe,
- .driver = {
- .name = "iqs7211",
- .of_match_table = iqs7211_of_match,
- .dev_groups = iqs7211_groups,
- .pm = pm_sleep_ptr(&iqs7211_pm),
- },
- };
- module_i2c_driver(iqs7211_i2c_driver);
- MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>");
- MODULE_DESCRIPTION("Azoteq IQS7210A/7211A/E Trackpad/Touchscreen Controller");
- MODULE_LICENSE("GPL");
|