1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2021 Oleh Kravchenko <oleg@kaa.org.ua>
5 * SparkFun Qwiic Joystick
6 * Product page:https://www.sparkfun.com/products/15168
7 * Firmware and hardware sources:https://github.com/sparkfun/Qwiic_Joystick
10 #include <linux/bits.h>
11 #include <linux/i2c.h>
12 #include <linux/input.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
16 #define DRV_NAME "qwiic-joystick"
18 #define QWIIC_JSK_REG_VERS 1
19 #define QWIIC_JSK_REG_DATA 3
21 #define QWIIC_JSK_MAX_AXIS GENMASK(9, 0)
22 #define QWIIC_JSK_FUZZ 2
23 #define QWIIC_JSK_FLAT 2
24 #define QWIIC_JSK_POLL_INTERVAL 16
25 #define QWIIC_JSK_POLL_MIN 8
26 #define QWIIC_JSK_POLL_MAX 32
30 struct input_dev
*dev
;
31 struct i2c_client
*client
;
45 static void qwiic_poll(struct input_dev
*input
)
47 struct qwiic_jsk
*priv
= input_get_drvdata(input
);
48 struct qwiic_data data
;
51 err
= i2c_smbus_read_i2c_block_data(priv
->client
, QWIIC_JSK_REG_DATA
,
52 sizeof(data
), (u8
*)&data
);
53 if (err
!= sizeof(data
))
56 input_report_abs(input
, ABS_X
, be16_to_cpu(data
.x
) >> 6);
57 input_report_abs(input
, ABS_Y
, be16_to_cpu(data
.y
) >> 6);
58 input_report_key(input
, BTN_THUMBL
, !data
.thumb
);
62 static int qwiic_probe(struct i2c_client
*client
)
64 struct qwiic_jsk
*priv
;
65 struct qwiic_ver vers
;
68 err
= i2c_smbus_read_i2c_block_data(client
, QWIIC_JSK_REG_VERS
,
69 sizeof(vers
), (u8
*)&vers
);
72 if (err
!= sizeof(vers
))
75 dev_dbg(&client
->dev
, "SparkFun Qwiic Joystick, FW: %u.%u\n",
76 vers
.major
, vers
.minor
);
78 priv
= devm_kzalloc(&client
->dev
, sizeof(*priv
), GFP_KERNEL
);
82 priv
->client
= client
;
83 snprintf(priv
->phys
, sizeof(priv
->phys
),
84 "i2c/%s", dev_name(&client
->dev
));
85 i2c_set_clientdata(client
, priv
);
87 priv
->dev
= devm_input_allocate_device(&client
->dev
);
91 priv
->dev
->id
.bustype
= BUS_I2C
;
92 priv
->dev
->name
= "SparkFun Qwiic Joystick";
93 priv
->dev
->phys
= priv
->phys
;
94 input_set_drvdata(priv
->dev
, priv
);
96 input_set_abs_params(priv
->dev
, ABS_X
, 0, QWIIC_JSK_MAX_AXIS
,
97 QWIIC_JSK_FUZZ
, QWIIC_JSK_FLAT
);
98 input_set_abs_params(priv
->dev
, ABS_Y
, 0, QWIIC_JSK_MAX_AXIS
,
99 QWIIC_JSK_FUZZ
, QWIIC_JSK_FLAT
);
100 input_set_capability(priv
->dev
, EV_KEY
, BTN_THUMBL
);
102 err
= input_setup_polling(priv
->dev
, qwiic_poll
);
104 dev_err(&client
->dev
, "failed to set up polling: %d\n", err
);
107 input_set_poll_interval(priv
->dev
, QWIIC_JSK_POLL_INTERVAL
);
108 input_set_min_poll_interval(priv
->dev
, QWIIC_JSK_POLL_MIN
);
109 input_set_max_poll_interval(priv
->dev
, QWIIC_JSK_POLL_MAX
);
111 err
= input_register_device(priv
->dev
);
113 dev_err(&client
->dev
, "failed to register joystick: %d\n", err
);
121 static const struct of_device_id of_qwiic_match
[] = {
122 { .compatible
= "sparkfun,qwiic-joystick", },
125 MODULE_DEVICE_TABLE(of
, of_qwiic_match
);
126 #endif /* CONFIG_OF */
128 static const struct i2c_device_id qwiic_id_table
[] = {
132 MODULE_DEVICE_TABLE(i2c
, qwiic_id_table
);
134 static struct i2c_driver qwiic_driver
= {
137 .of_match_table
= of_match_ptr(of_qwiic_match
),
139 .id_table
= qwiic_id_table
,
140 .probe
= qwiic_probe
,
142 module_i2c_driver(qwiic_driver
);
144 MODULE_AUTHOR("Oleh Kravchenko <oleg@kaa.org.ua>");
145 MODULE_DESCRIPTION("SparkFun Qwiic Joystick driver");
146 MODULE_LICENSE("GPL v2");