From patchwork Wed Jun 24 00:30:29 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: simon@mungewell.org X-Patchwork-Id: 6664321 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 746999F402 for ; Wed, 24 Jun 2015 00:30:47 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 83DC520698 for ; Wed, 24 Jun 2015 00:30:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8CA6620665 for ; Wed, 24 Jun 2015 00:30:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933797AbbFXAan (ORCPT ); Tue, 23 Jun 2015 20:30:43 -0400 Received: from host171.canaca.com ([67.55.55.225]:52077 "EHLO host171.canaca.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933554AbbFXAaj (ORCPT ); Tue, 23 Jun 2015 20:30:39 -0400 Received: from [208.118.126.162] (helo=LinuxBuild.TOPCON.COM) by host171.canaca.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.69) (envelope-from ) id 1Z7YaM-0000su-3w; Tue, 23 Jun 2015 20:30:38 -0400 From: Simon Wood To: linux-input@vger.kernel.org Cc: Frank Praznik , linux-iio@vger.kernel.org, Simon Wood Subject: [RFC_v2 3/4] HID: hid-sony: Add IIO trigger support for SixAxis Controller Date: Tue, 23 Jun 2015 18:30:29 -0600 Message-Id: <1435105830-2297-4-git-send-email-simon@mungewell.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1435105830-2297-1-git-send-email-simon@mungewell.org> References: <1435105830-2297-1-git-send-email-simon@mungewell.org> X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - host171.canaca.com X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - mungewell.org X-Source: X-Source-Args: X-Source-Dir: Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-8.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP --- drivers/hid/hid-sony.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index b7a7f0d..ce0526d 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -39,9 +39,11 @@ #include #include #include +#include #include #include #include +#include #include "hid-ids.h" @@ -855,9 +857,14 @@ enum sony_iio_axis { AXIS_ACC_Z, }; +static void sony_iio_trigger_work(struct irq_work *work); + struct sony_iio { struct sony_sc *sc; + struct iio_trigger *trig; + u8 buff[16]; /* 3x 16-bit + padding + timestamp */ + struct irq_work work; #endif }; @@ -1076,6 +1083,13 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, sc->last_data[AXIS_ACC_X] = (rd[42] << 8) + rd[41]; sc->last_data[AXIS_ACC_Y] = (rd[44] << 8) + rd[43]; sc->last_data[AXIS_ACC_Z] = (rd[46] << 8) + rd[45]; + + if (sc->indio_dev) { + struct sony_iio *data; + + data = iio_priv(sc->indio_dev); + sony_iio_trigger_work(&data->work); + } #endif sixaxis_parse_report(sc, rd, size); } else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 && @@ -1869,6 +1883,28 @@ static const struct iio_info sony_iio_info = { .driver_module = THIS_MODULE, }; +static void sony_iio_trigger_work(struct irq_work *work) +{ + struct sony_iio *data = container_of(work, struct sony_iio, work); + + iio_trigger_poll(data->trig); +} + +static ssize_t sony_iio_trigger_poll(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct iio_trigger *trig = to_iio_trigger(dev); + struct sony_iio *data = iio_trigger_get_drvdata(trig); + + irq_work_queue(&data->work); + + return count; +} + +static const struct iio_trigger_ops sony_iio_trigger_ops = { + .owner = THIS_MODULE, +}; + static irqreturn_t sony_iio_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; @@ -1910,11 +1946,29 @@ static int sony_iio_probe(struct sony_sc *sc) indio_dev->channels = sony_sixaxis_channels; indio_dev->num_channels = ARRAY_SIZE(sony_sixaxis_channels); + data->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, + indio_dev->id); + if (!data->trig) { + ret = -ENOMEM; + goto err; + } + + data->trig->dev.parent = &hdev->dev; + data->trig->ops = &sony_iio_trigger_ops; + iio_trigger_set_drvdata(data->trig, indio_dev); + indio_dev->trig = iio_trigger_get(data->trig); + + init_irq_work(&data->work, sony_iio_trigger_work); + + ret = iio_trigger_register(data->trig); + if (ret) + goto err_trigger_free; + ret = iio_triggered_buffer_setup(indio_dev, NULL, sony_iio_trigger_handler, NULL); if (ret < 0) { dev_err(&hdev->dev, "unable to setup iio triggered buffer\n"); - goto err; + goto err_trigger_unregister; } ret = iio_device_register(indio_dev); @@ -1926,6 +1980,11 @@ static int sony_iio_probe(struct sony_sc *sc) err_buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); +err_trigger_unregister: + if (data->trig) + iio_trigger_unregister(data->trig); +err_trigger_free: + iio_trigger_free(data->trig); err: kfree(indio_dev); sc->indio_dev = NULL; @@ -1934,11 +1993,19 @@ err: static void sony_iio_remove(struct sony_sc *sc) { + struct sony_iio *data; + if (!sc->indio_dev) return; - iio_device_unregister(sc->indio_dev); + data = iio_priv(sc->indio_dev); + iio_triggered_buffer_cleanup(sc->indio_dev); + if (data->trig) + iio_trigger_unregister(data->trig); + iio_trigger_free(data->trig); + iio_device_unregister(sc->indio_dev); + kfree(sc->indio_dev); sc->indio_dev = NULL; }