Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp2821136yba; Mon, 8 Apr 2019 05:35:12 -0700 (PDT) X-Google-Smtp-Source: APXvYqxzBayc87q34+r25hojyhghAuc5URbSexo9UefdkSZh/WgosefYMUKAfx3PlDCQ/mLFyjH9 X-Received: by 2002:a63:fd06:: with SMTP id d6mr28233584pgh.183.1554726912622; Mon, 08 Apr 2019 05:35:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1554726912; cv=none; d=google.com; s=arc-20160816; b=tEoHh2rUPLuLEjSdC2PamAMS+8S2g7d0VBnAdO+np85XtObUTlAL+j9iSHTWD29mNL 9symx3/FIrR9G36v0emLrVYQN/3RsssVJjszCt99/0OYwhQo28zaobM0fE8xi4Tag3yJ TR5YYSJz3LoqhMEOjBHd+Q8VBoN3OwVhfY50W+k7um7hnYBB12onkEpi5QorxBuud3Em 3yaE0WDwjKNQZEDNrp3IvPcQRPwNOeAKcQSB5xeUsG1HwsEc4a6RfNTJDmdPLWXRyWSR vAep2/CD1BBMAjUH3e6816fs6ZQxhtHA4ooD6kvR9ocFY8estrqyNwzCp+rFJp2wBe1M sKcA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:organization:in-reply-to :content-transfer-encoding:content-disposition:mime-version :references:message-id:subject:cc:to:from:date; bh=xFRoROO6HqpEAALpLPjdZ68AcD9y1B4bzvDxbLfdXjo=; b=BXsJNjsZuwJOeoC5J1KK9c3uYfQOcI2Fdlw5cOpddpQZz987pNVeJIqO58FP7C9k4t A+FdmLXzmTpRz6sf3X9cbCHvIQ8S4VJcDspVk/pq60+gE/CZjHznOBzEmA2sA/ucyepP jpI8bs8M4X4EdliMEYeU6PcKR08L0VnxYFQCFFmcZjMEH4ZLAX3IaNnfDNME4GZqvECV uq2b67fn7HRlRSbif1jsB6WAyFSvjsp23RbQPgTVAsgqzum19TLXKm+mzBWCFPbmxN/a OSw5vqfc0dptntVysHDhVUT1Kz12EqJ84EGD7T6nsBBUBhQUzbXI0hOCSFzNB/2t4KP1 piFQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g24si26742544pfd.212.2019.04.08.05.34.57; Mon, 08 Apr 2019 05:35:12 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726761AbfDHMds (ORCPT + 99 others); Mon, 8 Apr 2019 08:33:48 -0400 Received: from mga05.intel.com ([192.55.52.43]:22451 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726736AbfDHMdr (ORCPT ); Mon, 8 Apr 2019 08:33:47 -0400 X-Amp-Result: UNKNOWN X-Amp-Original-Verdict: FILE UNKNOWN X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Apr 2019 05:33:47 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,325,1549958400"; d="scan'208";a="133937131" Received: from smile.fi.intel.com (HELO smile) ([10.237.72.86]) by orsmga006.jf.intel.com with ESMTP; 08 Apr 2019 05:33:44 -0700 Received: from andy by smile with local (Exim 4.92) (envelope-from ) id 1hDTT5-0007f5-BV; Mon, 08 Apr 2019 15:33:43 +0300 Date: Mon, 8 Apr 2019 15:33:43 +0300 From: Andy Shevchenko To: Ronald =?iso-8859-1?Q?Tschal=E4r?= Cc: Dmitry Torokhov , Henrik Rydberg , Greg Kroah-Hartman , Lukas Wunner , Federico Lorenzi , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v4 2/2] Input: add Apple SPI keyboard and trackpad driver. Message-ID: <20190408123343.GO9224@smile.fi.intel.com> References: <20190407050358.2976-1-ronald@innovation.ch> <20190407050358.2976-3-ronald@innovation.ch> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20190407050358.2976-3-ronald@innovation.ch> Organization: Intel Finland Oy - BIC 0357606-4 - Westendinkatu 7, 02160 Espoo User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, Apr 06, 2019 at 10:03:58PM -0700, Ronald Tschal?r wrote: > The keyboard and trackpad on recent MacBook's (since 8,1) and > MacBookPro's (13,* and 14,*) are attached to an SPI controller instead > of USB, as previously. The higher level protocol is not publicly > documented and hence has been reverse engineered. As a consequence there > are still a number of unknown fields and commands. However, the known > parts have been working well and received extensive testing and use. > > In order for this driver to work, the proper SPI drivers need to be > loaded too; for MB8,1 these are spi_pxa2xx_platform and spi_pxa2xx_pci; > for all others they are spi_pxa2xx_platform and intel_lpss_pci. For this > reason enabling this driver in the config implies enabling the above > drivers. Thank you for an update, my comments below. > +static void applespi_debug_update_dimensions(struct applespi_data *applespi, > + const struct tp_finger *f) > +{ > + #define UPDATE_DIMENSIONS(val, op, last) \ > + do { \ > + if (le16_to_int(val) op last) \ > + last = le16_to_int(val); \ > + } while (0) I do not see how this is better than min()/max()/min_t()/max_t(). > + > + UPDATE_DIMENSIONS(f->abs_x, <, applespi->tp_dim_min_x); > + UPDATE_DIMENSIONS(f->abs_x, >, applespi->tp_dim_max_x); > + UPDATE_DIMENSIONS(f->abs_y, <, applespi->tp_dim_min_y); > + UPDATE_DIMENSIONS(f->abs_y, >, applespi->tp_dim_max_y); > + > + #undef UPDATE_DIMENSIONS > +} > +static void > +applespi_remap_fn_key(struct keyboard_protocol *keyboard_protocol) > +{ > + unsigned char tmp; What about u8 bit = BIT(fnremap - 1); > + if (!fnremap || fnremap > ARRAY_SIZE(applespi_controlcodes) || > + !applespi_controlcodes[fnremap - 1]) > + return; > + > + tmp = keyboard_protocol->fn_pressed; > + keyboard_protocol->fn_pressed = > + !!(keyboard_protocol->modifiers & BIT(fnremap - 1)); ... & bit); and so on? > + if (tmp) > + keyboard_protocol->modifiers |= BIT(fnremap - 1); > + else > + keyboard_protocol->modifiers &= ~BIT(fnremap - 1); > +} > +static void > +applespi_handle_keyboard_event(struct applespi_data *applespi, > + struct keyboard_protocol *keyboard_protocol) > +{ > + int i, j; > + unsigned int key; > + bool still_pressed; > + bool is_overflow; Perhaps reversed xmas tree order? > + > + compiletime_assert(ARRAY_SIZE(applespi_controlcodes) == > + sizeof_field(struct keyboard_protocol, modifiers) * 8, > + "applespi_controlcodes has wrong number of entries"); > + > + /* check for rollover overflow, which is signalled by all keys == 1 */ > + is_overflow = true; > + > + for (i = 0; i < MAX_ROLLOVER; i++) { > + if (keyboard_protocol->keys_pressed[i] != 1) { > + is_overflow = false; > + break; > + } > + } > + > + if (is_overflow) > + return; Isn't it simple if (i == MAX_ROLLOVER) w/o need of additional variable? > + /* remap fn key if desired */ > + applespi_remap_fn_key(keyboard_protocol); > + > + /* check released keys */ > + for (i = 0; i < MAX_ROLLOVER; i++) { > + still_pressed = false; > + for (j = 0; j < MAX_ROLLOVER; j++) { > + if (applespi->last_keys_pressed[i] == > + keyboard_protocol->keys_pressed[j]) { > + still_pressed = true; > + break; > + } > + } > + > + if (still_pressed) > + continue; Similar idea here. > + > + key = applespi_code_to_key(applespi->last_keys_pressed[i], > + applespi->last_keys_fn_pressed[i]); > + input_report_key(applespi->keyboard_input_dev, key, 0); > + applespi->last_keys_fn_pressed[i] = 0; > + } > + /* check pressed keys */ > + for (i = 0; i < MAX_ROLLOVER; i++) { > + if (keyboard_protocol->keys_pressed[i] < > + ARRAY_SIZE(applespi_scancodes) && > + keyboard_protocol->keys_pressed[i] > 0) { > + key = applespi_code_to_key( > + keyboard_protocol->keys_pressed[i], > + keyboard_protocol->fn_pressed); > + input_report_key(applespi->keyboard_input_dev, key, 1); > + applespi->last_keys_fn_pressed[i] = > + keyboard_protocol->fn_pressed; > + } > + } > + > + /* check control keys */ > + for (i = 0; i < ARRAY_SIZE(applespi_controlcodes); i++) { > + if (keyboard_protocol->modifiers & BIT(i)) > + input_report_key(applespi->keyboard_input_dev, > + applespi_controlcodes[i], 1); > + else > + input_report_key(applespi->keyboard_input_dev, > + applespi_controlcodes[i], 0); > + } > + > + /* check function key */ > + if (keyboard_protocol->fn_pressed && !applespi->last_fn_pressed) > + input_report_key(applespi->keyboard_input_dev, KEY_FN, 1); > + else if (!keyboard_protocol->fn_pressed && applespi->last_fn_pressed) > + input_report_key(applespi->keyboard_input_dev, KEY_FN, 0); > + applespi->last_fn_pressed = keyboard_protocol->fn_pressed; > + > + /* done */ > + input_sync(applespi->keyboard_input_dev); > + memcpy(&applespi->last_keys_pressed, keyboard_protocol->keys_pressed, > + sizeof(applespi->last_keys_pressed)); > +} > +static int > +applespi_register_touchpad_device(struct applespi_data *applespi, > + struct touchpad_info_protocol *rcvd_tp_info) > +{ > + const struct applespi_tp_info *tp_info; > + struct input_dev *touchpad_input_dev; > + int sts; > + > + /* set up touchpad dimensions */ > + tp_info = applespi_find_touchpad_info(rcvd_tp_info->model_no); > + if (!tp_info) { > + dev_warn(&(applespi)->spi->dev, I'm not sure what parens are helping with (here and everywhere with device parameter)? > + "Unknown touchpad model %x - falling back to MB8 touchpad\n", > + rcvd_tp_info->model_no); > + tp_info = &applespi_tp_models[0].tp_info; > + } > + return 0; > +} > +static int applespi_probe(struct spi_device *spi) > +{ > + struct applespi_data *applespi; > + acpi_status acpi_sts; > + int sts, i; > + unsigned long long gpe, usb_status; > + > + /* check if the USB interface is present and enabled already */ > + acpi_sts = acpi_evaluate_integer(ACPI_HANDLE(&spi->dev), "UIST", NULL, > + &usb_status); ... see below ... > + if (ACPI_SUCCESS(acpi_sts) && usb_status) { > + /* let the USB driver take over instead */ > + dev_info(&spi->dev, "USB interface already enabled\n"); > + return -ENODEV; > + } > + > + /* allocate driver data */ > + applespi = devm_kzalloc(&spi->dev, sizeof(*applespi), GFP_KERNEL); > + if (!applespi) > + return -ENOMEM; > + > + applespi->spi = spi; > + applespi->handle = ACPI_HANDLE(&spi->dev); AFAICS this is local variable, why put it in the data structure? And above you are not using this, btw. > + } else { > + struct dentry *ret; > + > + ret = debugfs_create_bool("enable_tp_dim", 0600, > + applespi->debugfs_root, > + &applespi->debug_tp_dim); > + if (IS_ERR(ret)) > + dev_warn(&(applespi)->spi->dev, > + "Error creating debugfs entry enable_tp_dim (%ld)\n", > + PTR_ERR(ret)); Can ret be NULL? dev_dbg() looks more appropriate. > + > + ret = debugfs_create_file("tp_dim", 0400, > + applespi->debugfs_root, applespi, > + &applespi_tp_dim_fops); > + if (IS_ERR(ret)) > + dev_warn(&(applespi)->spi->dev, > + "Error creating debugfs entry tp_dim (%ld)\n", > + PTR_ERR(ret)); Ditto. > + } > + > + return 0; > +} -- With Best Regards, Andy Shevchenko