Commit 50717edb authored by Dmitry Torokhov's avatar Dmitry Torokhov

Input: adc-joystick - move axes data into the main structure

There is no need to allocate axes information separately from the main
joystick structure so let's fold the allocation and also drop members
(such as range, flat and fuzz) that are only used during initialization
of the device.
Acked-by: default avatarArtur Rojek <contact@artur-rojek.eu>
Link: https://lore.kernel.org/r/ZmkrgTlxNwm_oHxv@google.comSigned-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 703f1267
...@@ -15,19 +15,15 @@ ...@@ -15,19 +15,15 @@
struct adc_joystick_axis { struct adc_joystick_axis {
u32 code; u32 code;
s32 range[2];
s32 fuzz;
s32 flat;
bool inverted; bool inverted;
}; };
struct adc_joystick { struct adc_joystick {
struct input_dev *input; struct input_dev *input;
struct iio_cb_buffer *buffer; struct iio_cb_buffer *buffer;
struct adc_joystick_axis *axes;
struct iio_channel *chans; struct iio_channel *chans;
int num_chans; unsigned int num_chans;
bool polled; struct adc_joystick_axis axes[] __counted_by(num_chans);
}; };
static int adc_joystick_invert(struct input_dev *dev, static int adc_joystick_invert(struct input_dev *dev,
...@@ -135,9 +131,11 @@ static void adc_joystick_cleanup(void *data) ...@@ -135,9 +131,11 @@ static void adc_joystick_cleanup(void *data)
static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy) static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy)
{ {
struct adc_joystick_axis *axes; struct adc_joystick_axis *axes = joy->axes;
struct fwnode_handle *child; struct fwnode_handle *child;
int num_axes, error, i; s32 range[2], fuzz, flat;
unsigned int num_axes;
int error, i;
num_axes = device_get_child_node_count(dev); num_axes = device_get_child_node_count(dev);
if (!num_axes) { if (!num_axes) {
...@@ -151,10 +149,6 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy) ...@@ -151,10 +149,6 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy)
return -EINVAL; return -EINVAL;
} }
axes = devm_kmalloc_array(dev, num_axes, sizeof(*axes), GFP_KERNEL);
if (!axes)
return -ENOMEM;
device_for_each_child_node(dev, child) { device_for_each_child_node(dev, child) {
error = fwnode_property_read_u32(child, "reg", &i); error = fwnode_property_read_u32(child, "reg", &i);
if (error) { if (error) {
...@@ -176,29 +170,25 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy) ...@@ -176,29 +170,25 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy)
} }
error = fwnode_property_read_u32_array(child, "abs-range", error = fwnode_property_read_u32_array(child, "abs-range",
axes[i].range, 2); range, 2);
if (error) { if (error) {
dev_err(dev, "abs-range invalid or missing\n"); dev_err(dev, "abs-range invalid or missing\n");
goto err_fwnode_put; goto err_fwnode_put;
} }
if (axes[i].range[0] > axes[i].range[1]) { if (range[0] > range[1]) {
dev_dbg(dev, "abs-axis %d inverted\n", i); dev_dbg(dev, "abs-axis %d inverted\n", i);
axes[i].inverted = true; axes[i].inverted = true;
swap(axes[i].range[0], axes[i].range[1]); swap(range[0], range[1]);
} }
fwnode_property_read_u32(child, "abs-fuzz", &axes[i].fuzz); fwnode_property_read_u32(child, "abs-fuzz", &fuzz);
fwnode_property_read_u32(child, "abs-flat", &axes[i].flat); fwnode_property_read_u32(child, "abs-flat", &flat);
input_set_abs_params(joy->input, axes[i].code, input_set_abs_params(joy->input, axes[i].code,
axes[i].range[0], axes[i].range[1], range[0], range[1], fuzz, flat);
axes[i].fuzz, axes[i].flat);
input_set_capability(joy->input, EV_ABS, axes[i].code);
} }
joy->axes = axes;
return 0; return 0;
err_fwnode_put: err_fwnode_put:
...@@ -206,23 +196,50 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy) ...@@ -206,23 +196,50 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy)
return error; return error;
} }
static int adc_joystick_count_channels(struct device *dev,
const struct iio_channel *chans,
bool polled,
unsigned int *num_chans)
{
int bits;
int i;
/*
* Count how many channels we got. NULL terminated.
* Do not check the storage size if using polling.
*/
for (i = 0; chans[i].indio_dev; i++) {
if (polled)
continue;
bits = chans[i].channel->scan_type.storagebits;
if (!bits || bits > 16) {
dev_err(dev, "Unsupported channel storage size\n");
return -EINVAL;
}
if (bits != chans[0].channel->scan_type.storagebits) {
dev_err(dev, "Channels must have equal storage size\n");
return -EINVAL;
}
}
*num_chans = i;
return 0;
}
static int adc_joystick_probe(struct platform_device *pdev) static int adc_joystick_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct iio_channel *chans;
struct adc_joystick *joy; struct adc_joystick *joy;
struct input_dev *input; struct input_dev *input;
unsigned int poll_interval = 0;
unsigned int num_chans;
int error; int error;
int bits;
int i;
unsigned int poll_interval;
joy = devm_kzalloc(dev, sizeof(*joy), GFP_KERNEL); chans = devm_iio_channel_get_all(dev);
if (!joy) error = PTR_ERR_OR_ZERO(chans);
return -ENOMEM; if (error) {
joy->chans = devm_iio_channel_get_all(dev);
if (IS_ERR(joy->chans)) {
error = PTR_ERR(joy->chans);
if (error != -EPROBE_DEFER) if (error != -EPROBE_DEFER)
dev_err(dev, "Unable to get IIO channels"); dev_err(dev, "Unable to get IIO channels");
return error; return error;
...@@ -236,28 +253,19 @@ static int adc_joystick_probe(struct platform_device *pdev) ...@@ -236,28 +253,19 @@ static int adc_joystick_probe(struct platform_device *pdev)
} else if (poll_interval == 0) { } else if (poll_interval == 0) {
dev_err(dev, "Unable to get poll-interval\n"); dev_err(dev, "Unable to get poll-interval\n");
return -EINVAL; return -EINVAL;
} else {
joy->polled = true;
} }
/* error = adc_joystick_count_channels(dev, chans, poll_interval != 0,
* Count how many channels we got. NULL terminated. &num_chans);
* Do not check the storage size if using polling. if (error)
*/ return error;
for (i = 0; joy->chans[i].indio_dev; i++) {
if (joy->polled) joy = devm_kzalloc(dev, struct_size(joy, axes, num_chans), GFP_KERNEL);
continue; if (!joy)
bits = joy->chans[i].channel->scan_type.storagebits; return -ENOMEM;
if (!bits || bits > 16) {
dev_err(dev, "Unsupported channel storage size\n"); joy->chans = chans;
return -EINVAL; joy->num_chans = num_chans;
}
if (bits != joy->chans[0].channel->scan_type.storagebits) {
dev_err(dev, "Channels must have equal storage size\n");
return -EINVAL;
}
}
joy->num_chans = i;
input = devm_input_allocate_device(dev); input = devm_input_allocate_device(dev);
if (!input) { if (!input) {
...@@ -273,7 +281,7 @@ static int adc_joystick_probe(struct platform_device *pdev) ...@@ -273,7 +281,7 @@ static int adc_joystick_probe(struct platform_device *pdev)
if (error) if (error)
return error; return error;
if (joy->polled) { if (poll_interval != 0) {
input_setup_polling(input, adc_joystick_poll); input_setup_polling(input, adc_joystick_poll);
input_set_poll_interval(input, poll_interval); input_set_poll_interval(input, poll_interval);
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment