Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2021 Oleh Kravchenko <oleg@kaa.org.ua>
0004  *
0005  * SparkFun Qwiic Joystick
0006  * Product page:https://www.sparkfun.com/products/15168
0007  * Firmware and hardware sources:https://github.com/sparkfun/Qwiic_Joystick
0008  */
0009 
0010 #include <linux/bits.h>
0011 #include <linux/i2c.h>
0012 #include <linux/input.h>
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 
0016 #define DRV_NAME "qwiic-joystick"
0017 
0018 #define QWIIC_JSK_REG_VERS  1
0019 #define QWIIC_JSK_REG_DATA  3
0020 
0021 #define QWIIC_JSK_MAX_AXIS  GENMASK(9, 0)
0022 #define QWIIC_JSK_FUZZ      2
0023 #define QWIIC_JSK_FLAT      2
0024 #define QWIIC_JSK_POLL_INTERVAL 16
0025 #define QWIIC_JSK_POLL_MIN  8
0026 #define QWIIC_JSK_POLL_MAX  32
0027 
0028 struct qwiic_jsk {
0029     char phys[32];
0030     struct input_dev *dev;
0031     struct i2c_client *client;
0032 };
0033 
0034 struct qwiic_ver {
0035     u8 major;
0036     u8 minor;
0037 };
0038 
0039 struct qwiic_data {
0040     __be16 x;
0041     __be16 y;
0042     u8 thumb;
0043 };
0044 
0045 static void qwiic_poll(struct input_dev *input)
0046 {
0047     struct qwiic_jsk *priv = input_get_drvdata(input);
0048     struct qwiic_data data;
0049     int err;
0050 
0051     err = i2c_smbus_read_i2c_block_data(priv->client, QWIIC_JSK_REG_DATA,
0052                         sizeof(data), (u8 *)&data);
0053     if (err != sizeof(data))
0054         return;
0055 
0056     input_report_abs(input, ABS_X, be16_to_cpu(data.x) >> 6);
0057     input_report_abs(input, ABS_Y, be16_to_cpu(data.y) >> 6);
0058     input_report_key(input, BTN_THUMBL, !data.thumb);
0059     input_sync(input);
0060 }
0061 
0062 static int qwiic_probe(struct i2c_client *client)
0063 {
0064     struct qwiic_jsk *priv;
0065     struct qwiic_ver vers;
0066     int err;
0067 
0068     err = i2c_smbus_read_i2c_block_data(client, QWIIC_JSK_REG_VERS,
0069                         sizeof(vers), (u8 *)&vers);
0070     if (err < 0)
0071         return err;
0072     if (err != sizeof(vers))
0073         return -EIO;
0074 
0075     dev_dbg(&client->dev, "SparkFun Qwiic Joystick, FW: %u.%u\n",
0076         vers.major, vers.minor);
0077 
0078     priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
0079     if (!priv)
0080         return -ENOMEM;
0081 
0082     priv->client = client;
0083     snprintf(priv->phys, sizeof(priv->phys),
0084          "i2c/%s", dev_name(&client->dev));
0085     i2c_set_clientdata(client, priv);
0086 
0087     priv->dev = devm_input_allocate_device(&client->dev);
0088     if (!priv->dev)
0089         return -ENOMEM;
0090 
0091     priv->dev->id.bustype = BUS_I2C;
0092     priv->dev->name = "SparkFun Qwiic Joystick";
0093     priv->dev->phys = priv->phys;
0094     input_set_drvdata(priv->dev, priv);
0095 
0096     input_set_abs_params(priv->dev, ABS_X, 0, QWIIC_JSK_MAX_AXIS,
0097                  QWIIC_JSK_FUZZ, QWIIC_JSK_FLAT);
0098     input_set_abs_params(priv->dev, ABS_Y, 0, QWIIC_JSK_MAX_AXIS,
0099                  QWIIC_JSK_FUZZ, QWIIC_JSK_FLAT);
0100     input_set_capability(priv->dev, EV_KEY, BTN_THUMBL);
0101 
0102     err = input_setup_polling(priv->dev, qwiic_poll);
0103     if (err) {
0104         dev_err(&client->dev, "failed to set up polling: %d\n", err);
0105         return err;
0106     }
0107     input_set_poll_interval(priv->dev, QWIIC_JSK_POLL_INTERVAL);
0108     input_set_min_poll_interval(priv->dev, QWIIC_JSK_POLL_MIN);
0109     input_set_max_poll_interval(priv->dev, QWIIC_JSK_POLL_MAX);
0110 
0111     err = input_register_device(priv->dev);
0112     if (err) {
0113         dev_err(&client->dev, "failed to register joystick: %d\n", err);
0114         return err;
0115     }
0116 
0117     return 0;
0118 }
0119 
0120 #ifdef CONFIG_OF
0121 static const struct of_device_id of_qwiic_match[] = {
0122     { .compatible = "sparkfun,qwiic-joystick", },
0123     { },
0124 };
0125 MODULE_DEVICE_TABLE(of, of_qwiic_match);
0126 #endif /* CONFIG_OF */
0127 
0128 static const struct i2c_device_id qwiic_id_table[] = {
0129     { KBUILD_MODNAME, 0 },
0130     { },
0131 };
0132 MODULE_DEVICE_TABLE(i2c, qwiic_id_table);
0133 
0134 static struct i2c_driver qwiic_driver = {
0135     .driver = {
0136         .name       = DRV_NAME,
0137         .of_match_table = of_match_ptr(of_qwiic_match),
0138     },
0139     .id_table   = qwiic_id_table,
0140     .probe_new  = qwiic_probe,
0141 };
0142 module_i2c_driver(qwiic_driver);
0143 
0144 MODULE_AUTHOR("Oleh Kravchenko <oleg@kaa.org.ua>");
0145 MODULE_DESCRIPTION("SparkFun Qwiic Joystick driver");
0146 MODULE_LICENSE("GPL v2");