diff options
-rw-r--r-- | drivers/input/touchscreen/touch_offload.c | 62 |
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); |