Received: by 10.192.165.148 with SMTP id m20csp3684920imm; Mon, 23 Apr 2018 10:31:59 -0700 (PDT) X-Google-Smtp-Source: AIpwx4+//xUTNeeZlD1cBuQuy8bNScGGgZaYSdCPFaowI2GJRJpg8MfTWInT/CLgqtLcPm6xFB4D X-Received: by 2002:a17:902:9a8c:: with SMTP id w12-v6mr22016582plp.333.1524504719052; Mon, 23 Apr 2018 10:31:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524504719; cv=none; d=google.com; s=arc-20160816; b=gmzRCHa5b4U8PuQH6hUilvgOLSAJjnCimyolqCGgvTWTisLZDl3yuyPbvLLqRoIk+3 EFRSsWJPpxoZ8GHy0ZaW9kxEXoA0xIikthbV6AUqfvamvFNwvM2firfkgOIWZ8MNw7Az n96QcHr2DQYUODzQqxy/b988DUPaMLFHkbkjjpK6tYffzqnza3Zjs2LPOVaeYKHlrR6K xAa0LaQwYnMM8qLaxETtrPmHnjdQuOU1/5WtPu1yS1dP0lKYUxkG6dUJRYK+g/ApmAlu uwso4j1S2VH0PEkh6CYfgh2+WT9lBMSt1582ZYWQRszZdnEZPUGX8Ai4XVxrCxvHyST/ 7QMA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature:arc-authentication-results; bh=HPJ8X33O3i7Ju+vjUURIcQm8DZRf+QY3EKgpYo7N7ig=; b=w9E5mOGyxFQiCHnQdL4USGik30+wRgCiXyHkz4VRg0Iy1F1+WcHBtKg+xMY8oStdmy AqfYZuG9zXURpWUZhiIF1gbv1oI4KrMEIgQESHoBgxgrJWrASfFvP6gXzJTf6HYL0kS+ DhoCwN2TA+1SkTmG44bjJ4az1mzlFIoitHl35OtSRfihBKPoDvzi3odC0zmCqHzoSpgV yHBmuEfle+HRzwNAuWeo0iygRBruYcda3aN7Wob0iVOER96c/BrbIlImoi249Kn530ax ZEjItnu5uqWsJmT4rhZdSIoQVvQ1Lbj0iP3d/731WuCpkf5ffdv0KJqv3R5HYvzOWpc0 kKdw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=Z5n0eSTF; 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=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q127si11201781pfb.1.2018.04.23.10.31.44; Mon, 23 Apr 2018 10:31:59 -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; dkim=pass header.i=@gmail.com header.s=20161025 header.b=Z5n0eSTF; 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=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932189AbeDWR3p (ORCPT + 99 others); Mon, 23 Apr 2018 13:29:45 -0400 Received: from mail-pg0-f68.google.com ([74.125.83.68]:45770 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932073AbeDWR3m (ORCPT ); Mon, 23 Apr 2018 13:29:42 -0400 Received: by mail-pg0-f68.google.com with SMTP id i29so7344230pgn.12; Mon, 23 Apr 2018 10:29:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=HPJ8X33O3i7Ju+vjUURIcQm8DZRf+QY3EKgpYo7N7ig=; b=Z5n0eSTFPB9XbV4+fKB8QdVdFbuv9vJ3Dnb5f0cmbOB3x2v71w6VvCMhPM6JCqEE5i GoLcJgxn3sokRer9Bj/GcCezOvC39THPIiuiuTIDy9UaE6IJeVJQhjRgmTGCf/vrfOSY UrbilCBhbZGHOnvmefn44tXA7BolbAZCdWbuZNrH3lrDAj9Bp3VA4TCadQUe8OER3lRT V6EArbrLGx0jbrWQE8Ti1xWID/7qXsvGPs6R2fBZJWBMecQbpXnoS9k4koKXz2pDVxvD KBLJqPZoXYfjMIx13mLuGZvTHMHU5cCzehexsENjWxiiZ0uWJa8kU5A16aWOCV6qCQKm F5LQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=HPJ8X33O3i7Ju+vjUURIcQm8DZRf+QY3EKgpYo7N7ig=; b=ovUFxSLx4kFgNKri5+/q8Xx+wQXmXsRVE26lkXArk5gycnNdEzzw/V8xGc+ElN9TLO gmP47+can5/Zo/WBgTGsx92f46RqVXgUJZZxL1FTU3Qw7ySOz/Vf2aGJX8JdIRL2HEQ8 e1JOPzY675uZzeEMpDLJJdRGWyTY42hdB3rQ7lDadradZMXjnYchsfw17amS9j6ClN5/ 9jz3hTr91vkkSyu2ohGbcHN+bmXLNmsvKztNEjDcIG9/Nl+gmaeXFOcxBzXzaWAZyzsp WkJFffrhlRrIm1npFXWAjdtrA9B6lHGvOWT9WUoGqzHqiIUlh2sxFkalEF0GlW+e/1Zl JJvA== X-Gm-Message-State: ALQs6tCPbsVIh/lgYSC0qaofDk9TOwkLoDRJ67xLXGCZ3GeO/uCmn0z7 I2IKrEr6Uca1gq8Ha8FH00Eq4N6c X-Received: by 10.101.70.8 with SMTP id v8mr17651987pgq.336.1524504580873; Mon, 23 Apr 2018 10:29:40 -0700 (PDT) Received: from dtor-ws ([2620:0:1000:1511:8de6:27a8:ed13:2ef5]) by smtp.gmail.com with ESMTPSA id y15sm23669489pfb.37.2018.04.23.10.29.39 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 23 Apr 2018 10:29:39 -0700 (PDT) Date: Mon, 23 Apr 2018 10:29:37 -0700 From: Dmitry Torokhov To: Baolin Wang Cc: robh+dt@kernel.org, mark.rutland@arm.com, orsonzhai@gmail.com, zhang.lyra@gmail.com, linux-input@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, xiaotong.lu@spreadtrum.com Subject: Re: [PATCH v2 2/2] input: misc: Add Spreadtrum vibrator driver Message-ID: <20180423172937.GA66646@dtor-ws> References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.9.2 (2017-12-15) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Xiaotong, On Mon, Apr 23, 2018 at 10:33:36AM +0800, Baolin Wang wrote: > From: Xiaotong Lu > > This patch adds the Spreadtrum vibrator driver, which embedded in the > Spreadtrum SC27xx series PMICs. > > Signed-off-by: Xiaotong Lu > Signed-off-by: Baolin Wang > --- > Changes since v1: > - Remove input_ff_destroy() and input_unregister_device() > --- > drivers/input/misc/Kconfig | 10 +++ > drivers/input/misc/Makefile | 1 + > drivers/input/misc/sc27xx-vibra.c | 156 +++++++++++++++++++++++++++++++++++++ > 3 files changed, 167 insertions(+) > create mode 100644 drivers/input/misc/sc27xx-vibra.c > > diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig > index 572b15f..c761c0c 100644 > --- a/drivers/input/misc/Kconfig > +++ b/drivers/input/misc/Kconfig > @@ -841,4 +841,14 @@ config INPUT_RAVE_SP_PWRBUTTON > To compile this driver as a module, choose M here: the > module will be called rave-sp-pwrbutton. > > +config INPUT_SC27XX_VIBRA > + tristate "Spreadtrum sc27xx vibrator support" > + depends on MFD_SC27XX_PMIC || COMPILE_TEST > + select INPUT_FF_MEMLESS > + help > + This option enables support for Spreadtrum sc27xx vibrator driver. > + > + To compile this driver as a module, choose M here. The module will > + be called sc27xx_vibra. > + > endif > diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile > index 72cde28..9d0f9d1 100644 > --- a/drivers/input/misc/Makefile > +++ b/drivers/input/misc/Makefile > @@ -66,6 +66,7 @@ obj-$(CONFIG_INPUT_RETU_PWRBUTTON) += retu-pwrbutton.o > obj-$(CONFIG_INPUT_AXP20X_PEK) += axp20x-pek.o > obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o > obj-$(CONFIG_INPUT_RK805_PWRKEY) += rk805-pwrkey.o > +obj-$(CONFIG_INPUT_SC27XX_VIBRA) += sc27xx-vibra.o > obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o > obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o > obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY) += soc_button_array.o > diff --git a/drivers/input/misc/sc27xx-vibra.c b/drivers/input/misc/sc27xx-vibra.c > new file mode 100644 > index 0000000..f78e70f > --- /dev/null > +++ b/drivers/input/misc/sc27xx-vibra.c > @@ -0,0 +1,156 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2018 Spreadtrum Communications Inc. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define CUR_DRV_CAL_SEL GENMASK(13, 12) > +#define SLP_LDOVIBR_PD_EN BIT(9) > +#define LDO_VIBR_PD BIT(8) > + > +struct vibra_info { > + struct input_dev *input_dev; > + struct work_struct play_work; > + struct regmap *regmap; > + u32 base; > + u32 strength; > + bool enabled; > +}; > + > +static void sc27xx_vibra_set(struct vibra_info *info, bool on) > +{ > + if (on) { > + regmap_update_bits(info->regmap, info->base, LDO_VIBR_PD, 0); > + regmap_update_bits(info->regmap, info->base, > + SLP_LDOVIBR_PD_EN, 0); > + info->enabled = true; > + } else { > + regmap_update_bits(info->regmap, info->base, LDO_VIBR_PD, > + LDO_VIBR_PD); > + regmap_update_bits(info->regmap, info->base, > + SLP_LDOVIBR_PD_EN, SLP_LDOVIBR_PD_EN); > + info->enabled = false; > + } > +} > + > +static int sc27xx_vibra_hw_init(struct vibra_info *info) > +{ > + return regmap_update_bits(info->regmap, info->base, CUR_DRV_CAL_SEL, 0); > +} > + > +static void sc27xx_vibra_play_work(struct work_struct *work) > +{ > + struct vibra_info *info = container_of(work, struct vibra_info, > + play_work); > + > + if (info->strength && !info->enabled) > + sc27xx_vibra_set(info, true); > + else if (info->enabled) > + sc27xx_vibra_set(info, false); I do not think this is correct. If you issue 2 play requests with info->strength that is not 0 then you'll end up disabling the vibrator. I think you want the 2nd condition to be: else if (info->strength == 0 && info->enabled) sc27xx_vibra_set(info, false); > +} > + > +static int sc27xx_vibra_play(struct input_dev *input, void *data, > + struct ff_effect *effect) > +{ > + struct vibra_info *info = input_get_drvdata(input); > + > + info->strength = effect->u.rumble.weak_magnitude; > + schedule_work(&info->play_work); > + > + return 0; > +} > + > +static void sc27xx_vibra_close(struct input_dev *input) > +{ > + struct vibra_info *info = input_get_drvdata(input); > + > + cancel_work_sync(&info->play_work); > + if (info->enabled) > + sc27xx_vibra_set(info, false); > +} > + > +static int sc27xx_vibra_probe(struct platform_device *pdev) > +{ > + struct device_node *node = pdev->dev.of_node; > + struct vibra_info *info; > + int ret; Can we please call this variable "error"? > + > + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); > + if (!info) > + return -ENOMEM; > + > + info->regmap = dev_get_regmap(pdev->dev.parent, NULL); > + if (!info->regmap) { > + dev_err(&pdev->dev, "failed to get vibrator regmap.\n"); > + return -ENODEV; > + } > + > + ret = of_property_read_u32(node, "reg", &info->base); I am fan of generic device properties, please change to device_property_read_u32(). > + if (ret) { > + dev_err(&pdev->dev, "failed to get vibrator base address.\n"); > + return ret; > + } > + > + info->input_dev = devm_input_allocate_device(&pdev->dev); > + if (!info->input_dev) { > + dev_err(&pdev->dev, "failed to allocate input device.\n"); > + return -ENOMEM; > + } > + > + info->input_dev->name = "sc27xx:vibrator"; > + info->input_dev->id.version = 0; > + info->input_dev->dev.parent = pdev->dev.parent; Why is device reparented to the parent of platform device? This breaks devm implementation for the input device. If you really need this, you'll have to switch to unmanaged API. > + info->input_dev->close = sc27xx_vibra_close; > + > + input_set_drvdata(info->input_dev, info); > + input_set_capability(info->input_dev, EV_FF, FF_RUMBLE); > + INIT_WORK(&info->play_work, sc27xx_vibra_play_work); > + info->enabled = false; > + > + ret = input_ff_create_memless(info->input_dev, NULL, sc27xx_vibra_play); > + if (ret) { > + dev_err(&pdev->dev, "failed to register vibrator to FF.\n"); > + return ret; > + } > + > + ret = input_register_device(info->input_dev); > + if (ret) { > + dev_err(&pdev->dev, "failed to register input device.\n"); > + return ret; > + } > + > + ret = sc27xx_vibra_hw_init(info); > + if (ret) { > + dev_err(&pdev->dev, "failed to initialize the vibrator.\n"); > + return ret; > + } It is too late to initialize hardware after registering the input device, as once registered it should be fully functional. I'd recommend calling this before calling input_register_device(), or (maybe even better) doing this as part of open() method. > + > + platform_set_drvdata(pdev, info); I do not think you are using platform device's driver data anywhere. > + return 0; > +} > + > +static const struct of_device_id sc27xx_vibra_of_match[] = { > + { .compatible = "sprd,sc27xx-vibrator", }, > + {} > +}; > +MODULE_DEVICE_TABLE(of, sc27xx_vibra_of_match); > + > +static struct platform_driver sc27xx_vibra_driver = { > + .driver = { > + .name = "sc27xx-vibrator", > + .of_match_table = sc27xx_vibra_of_match, Do you need suspend support by chance? To shut off the vibrator when system transitions to sleep? > + }, > + .probe = sc27xx_vibra_probe, > +}; > + > +module_platform_driver(sc27xx_vibra_driver); > + > +MODULE_DESCRIPTION("Spreadtrum SC27xx Vibrator Driver"); > +MODULE_LICENSE("GPL v2"); > +MODULE_AUTHOR("Xiaotong Lu "); > -- > 1.7.9.5 > Thanks. -- Dmitry