summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/input/touchscreen/touch_offload.c62
1 files changed, 59 insertions, 3 deletions
diff --git a/drivers/input/touchscreen/touch_offload.c b/drivers/input/touchscreen/touch_offload.c
index 59c4e92a4971..b1910c3a7837 100644
--- a/drivers/input/touchscreen/touch_offload.c
+++ b/drivers/input/touchscreen/touch_offload.c
@@ -79,6 +79,12 @@ static int pack_frame(struct touch_offload_context *context,
channel_size =
TOUCH_OFFLOAD_FRAME_SIZE_1D(context->caps.rx_size,
context->caps.tx_size);
+ else if (frame->channel_type[i] ==
+ CONTEXT_CHANNEL_TYPE_DRIVER_STATUS)
+ channel_size = TOUCH_OFFLOAD_FRAME_SIZE_DRIVER_STATUS;
+ else if (frame->channel_type[i] ==
+ CONTEXT_CHANNEL_TYPE_STYLUS_STATUS)
+ channel_size = TOUCH_OFFLOAD_FRAME_SIZE_STYLUS_STATUS;
else {
pr_err("%s: Invalid channel_type = 0x%08X", __func__,
frame->channel_type[i]);
@@ -221,7 +227,8 @@ static int touch_offload_allocate_buffers(struct touch_offload_context *context,
num_channels = (context->config.read_coords ? 1 : 0) +
hweight_long(context->config.mutual_data_types) +
- hweight_long(context->config.self_data_types);
+ hweight_long(context->config.self_data_types) +
+ hweight_long(context->config.context_channel_types);
if (num_channels == 0 || num_channels > MAX_CHANNELS) {
pr_err("%s: Configuration enables more (%d) than %d channels!\n",
__func__, num_channels, MAX_CHANNELS);
@@ -309,6 +316,44 @@ static int touch_offload_allocate_buffers(struct touch_offload_context *context,
chan++;
}
}
+ for (mask = CONTEXT_CHANNEL_BIT_START;
+ mask <= CONTEXT_CHANNEL_BIT_END;
+ mask <<= 1) {
+ struct TouchOffloadChannelHeader *chan_header;
+
+ if (!(context->config.context_channel_types & mask))
+ continue;
+
+ frame->channel_type[chan] = mask;
+ size = 0;
+ switch (mask) {
+ case CONTEXT_CHANNEL_TYPE_DRIVER_STATUS:
+ size =
+ TOUCH_OFFLOAD_FRAME_SIZE_DRIVER_STATUS;
+ break;
+ case CONTEXT_CHANNEL_TYPE_STYLUS_STATUS:
+ size =
+ TOUCH_OFFLOAD_FRAME_SIZE_STYLUS_STATUS;
+ break;
+ default:
+ pr_err("%s: Invalid channel_type = 0x%08X",
+ __func__, mask);
+ goto invalid_context_channel;
+ }
+ frame->channel_data[chan] = kzalloc(size,
+ GFP_KERNEL);
+ if (frame->channel_data[chan] == NULL)
+ goto kzalloc_channel_fail;
+
+ chan_header =
+ (struct TouchOffloadChannelHeader *)
+ frame->channel_data[chan];
+ chan_header->channel_type = mask;
+ chan_header->channel_size = size;
+ frame->channel_data_size[chan] = size;
+ frame->header.frame_size += size;
+ chan++;
+ }
frame->num_channels = chan;
frame->header.num_channels = chan;
@@ -327,6 +372,7 @@ static int touch_offload_allocate_buffers(struct touch_offload_context *context,
mutex_unlock(&context->buffer_lock);
return 0;
+invalid_context_channel:
kzalloc_channel_fail:
/* Free all channels of "frame" before returning */
if (frame)
@@ -452,7 +498,9 @@ static long touch_offload_ioctl(struct file *file, unsigned int ioctl_num,
(configure.config.filter_grip &&
!context->caps.filter_grip) ||
(configure.config.filter_palm &&
- !context->caps.filter_palm)) {
+ !context->caps.filter_palm) ||
+ (configure.config.auto_reporting &&
+ !context->caps.auto_reporting)) {
pr_err("%s: Invalid configuration enables unsupported features!\n",
__func__);
err = -EINVAL;
@@ -471,13 +519,21 @@ static long touch_offload_ioctl(struct file *file, unsigned int ioctl_num,
__func__);
err = -EINVAL;
return err;
+ } else if ((configure.config.context_channel_types &
+ ~context->caps.context_channel_types) != 0) {
+ pr_err("%s: Invalid configuration enables unsupported context types!\n",
+ __func__);
+ err = -EINVAL;
+ return err;
}
num_channels = (configure.config.read_coords ? 1 : 0) +
hweight_long(
configure.config.mutual_data_types) +
hweight_long(
- configure.config.self_data_types);
+ configure.config.self_data_types) +
+ hweight_long(
+ configure.config.context_channel_types);
if (num_channels <= 0 || num_channels > MAX_CHANNELS) {
pr_err("%s: Invalid configuration enables more (%d) than %d channels!\n",
__func__, num_channels, MAX_CHANNELS);