diff options
author | Linux Build Service Account <lnxbuild@quicinc.com> | 2017-06-03 22:36:45 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-06-03 22:36:45 -0700 |
commit | 0a3cd753f41fae73f31e16c038df78435bb6f8cf (patch) | |
tree | f2a043a0b10424b29aca66e3419484ce56eb1c35 /drivers/input/touchscreen | |
parent | 3fa75749848071c8a3eb7c80cd47af29089c6fb7 (diff) | |
parent | 84e36fe54696b592ec835149727a491757c48d8d (diff) |
Merge "input: synaptics_dsx: remove unused synaptics touch screen driver files"
Diffstat (limited to 'drivers/input/touchscreen')
4 files changed, 0 insertions, 1505 deletions
diff --git a/drivers/input/touchscreen/synaptics_dsx/Kconfig b/drivers/input/touchscreen/synaptics_dsx/Kconfig index 86263fddacea..18d473969261 100644 --- a/drivers/input/touchscreen/synaptics_dsx/Kconfig +++ b/drivers/input/touchscreen/synaptics_dsx/Kconfig @@ -50,17 +50,6 @@ config TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21 To compile this driver as a module, choose M here: the module will be called synaptics_dsx_core. -config TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v21 - tristate "Synaptics DSX touchscreen RMI device module" - depends on TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21 - help - Say Y here to enable support for direct RMI register access. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called synaptics_dsx_rmi_dev. - config TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v21 tristate "Synaptics DSX touchscreen firmware update module" depends on TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21 @@ -72,15 +61,4 @@ config TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v21 To compile this driver as a module, choose M here: the module will be called synaptics_dsx_fw_update. -config TOUCHSCREEN_SYNAPTICS_DSX_PROXIMITY_v21 - tristate "Synaptics DSX touchscreen proximity module" - depends on TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21 - help - Say Y here to enable support for proximity functionalities. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called synaptics_dsx_proximity. - endif diff --git a/drivers/input/touchscreen/synaptics_dsx/Makefile b/drivers/input/touchscreen/synaptics_dsx/Makefile index b35b222d5ae2..0bffb8da94ea 100644 --- a/drivers/input/touchscreen/synaptics_dsx/Makefile +++ b/drivers/input/touchscreen/synaptics_dsx/Makefile @@ -7,6 +7,4 @@ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_I2C_v21) += synaptics_dsx_i2c.o obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_SPI_v21) += synaptics_dsx_spi.o obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v21) += synaptics_dsx_core.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v21) += synaptics_dsx_rmi_dev.o obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v21) += synaptics_dsx_fw_update.o -obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_PROXIMITY_v21) += synaptics_dsx_proximity.o diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_proximity.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_proximity.c deleted file mode 100755 index 99c05e6845c0..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_proximity.c +++ /dev/null @@ -1,671 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012 Synaptics Incorporated - * - * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> - * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/input.h> -#include <linux/platform_device.h> -#include <linux/input/synaptics_dsx_v2.h> -#include "synaptics_dsx_core.h" - -#define PROX_PHYS_NAME "synaptics_dsx/input1" - -#define HOVER_Z_MAX (255) - -#define HOVERING_FINGER_EN (1 << 4) - -static ssize_t synaptics_rmi4_hover_finger_en_show(struct device *dev, - struct device_attribute *attr, char *buf); - -static ssize_t synaptics_rmi4_hover_finger_en_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static struct device_attribute attrs[] = { - __ATTR(hover_finger_en, (S_IRUGO | S_IWUGO), - synaptics_rmi4_hover_finger_en_show, - synaptics_rmi4_hover_finger_en_store), -}; - -struct synaptics_rmi4_f12_query_5 { - union { - struct { - unsigned char size_of_query6; - struct { - unsigned char ctrl0_is_present:1; - unsigned char ctrl1_is_present:1; - unsigned char ctrl2_is_present:1; - unsigned char ctrl3_is_present:1; - unsigned char ctrl4_is_present:1; - unsigned char ctrl5_is_present:1; - unsigned char ctrl6_is_present:1; - unsigned char ctrl7_is_present:1; - } __packed; - struct { - unsigned char ctrl8_is_present:1; - unsigned char ctrl9_is_present:1; - unsigned char ctrl10_is_present:1; - unsigned char ctrl11_is_present:1; - unsigned char ctrl12_is_present:1; - unsigned char ctrl13_is_present:1; - unsigned char ctrl14_is_present:1; - unsigned char ctrl15_is_present:1; - } __packed; - struct { - unsigned char ctrl16_is_present:1; - unsigned char ctrl17_is_present:1; - unsigned char ctrl18_is_present:1; - unsigned char ctrl19_is_present:1; - unsigned char ctrl20_is_present:1; - unsigned char ctrl21_is_present:1; - unsigned char ctrl22_is_present:1; - unsigned char ctrl23_is_present:1; - } __packed; - }; - unsigned char data[4]; - }; -}; - -struct synaptics_rmi4_f12_query_8 { - union { - struct { - unsigned char size_of_query9; - struct { - unsigned char data0_is_present:1; - unsigned char data1_is_present:1; - unsigned char data2_is_present:1; - unsigned char data3_is_present:1; - unsigned char data4_is_present:1; - unsigned char data5_is_present:1; - unsigned char data6_is_present:1; - unsigned char data7_is_present:1; - } __packed; - }; - unsigned char data[2]; - }; -}; - -struct prox_finger_data { - union { - struct { - unsigned char object_type_and_status; - unsigned char x_lsb; - unsigned char x_msb; - unsigned char y_lsb; - unsigned char y_msb; - unsigned char z; - } __packed; - unsigned char proximity_data[6]; - }; -}; - -struct synaptics_rmi4_prox_handle { - bool hover_finger_present; - bool hover_finger_en; - unsigned char intr_mask; - unsigned short query_base_addr; - unsigned short control_base_addr; - unsigned short data_base_addr; - unsigned short command_base_addr; - unsigned short hover_finger_en_addr; - unsigned short hover_finger_data_addr; - struct input_dev *prox_dev; - struct prox_finger_data *finger_data; - struct synaptics_rmi4_data *rmi4_data; -}; - -static struct synaptics_rmi4_prox_handle *prox; - -DECLARE_COMPLETION(prox_remove_complete); - -static void prox_hover_finger_lift(void) -{ - input_report_key(prox->prox_dev, BTN_TOUCH, 0); - input_report_key(prox->prox_dev, BTN_TOOL_FINGER, 0); - input_sync(prox->prox_dev); - prox->hover_finger_present = false; - - return; -} - -static void prox_hover_finger_report(void) -{ - int retval; - int x; - int y; - int z; - struct prox_finger_data *data; - struct synaptics_rmi4_data *rmi4_data = prox->rmi4_data; - - data = prox->finger_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - prox->hover_finger_data_addr, - data->proximity_data, - sizeof(data->proximity_data)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read hovering finger data\n", - __func__); - return; - } - - if (data->object_type_and_status != F12_HOVERING_FINGER_STATUS) { - if (prox->hover_finger_present) - prox_hover_finger_lift(); - - return; - } - - x = (data->x_msb << 8) | (data->x_lsb); - y = (data->y_msb << 8) | (data->y_lsb); - z = HOVER_Z_MAX - data->z; - - input_report_key(prox->prox_dev, BTN_TOUCH, 0); - input_report_key(prox->prox_dev, BTN_TOOL_FINGER, 1); - input_report_abs(prox->prox_dev, ABS_X, x); - input_report_abs(prox->prox_dev, ABS_Y, y); - input_report_abs(prox->prox_dev, ABS_DISTANCE, z); - - input_sync(prox->prox_dev); - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: x = %d y = %d z = %d\n", - __func__, x, y, z); - - prox->hover_finger_present = true; - - return; -} - -static int prox_set_hover_finger_en(void) -{ - int retval; - unsigned char object_report_enable; - struct synaptics_rmi4_data *rmi4_data = prox->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - prox->hover_finger_en_addr, - &object_report_enable, - sizeof(object_report_enable)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read from object report enable register\n", - __func__); - return retval; - } - - if (prox->hover_finger_en) - object_report_enable |= HOVERING_FINGER_EN; - else - object_report_enable &= ~HOVERING_FINGER_EN; - - retval = synaptics_rmi4_reg_write(rmi4_data, - prox->hover_finger_en_addr, - &object_report_enable, - sizeof(object_report_enable)); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write to object report enable register\n", - __func__); - return retval; - } - - return 0; -} - -static void prox_set_params(void) -{ - input_set_abs_params(prox->prox_dev, ABS_X, 0, - prox->rmi4_data->sensor_max_x, 0, 0); - input_set_abs_params(prox->prox_dev, ABS_Y, 0, - prox->rmi4_data->sensor_max_y, 0, 0); - input_set_abs_params(prox->prox_dev, ABS_DISTANCE, 0, - HOVER_Z_MAX, 0, 0); - - return; -} - -static int prox_reg_init(void) -{ - int retval; - unsigned char ctrl_23_offset; - unsigned char data_1_offset; - struct synaptics_rmi4_f12_query_5 query_5; - struct synaptics_rmi4_f12_query_8 query_8; - struct synaptics_rmi4_data *rmi4_data = prox->rmi4_data; - - retval = synaptics_rmi4_reg_read(rmi4_data, - prox->query_base_addr + 5, - query_5.data, - sizeof(query_5.data)); - if (retval < 0) - return retval; - - ctrl_23_offset = query_5.ctrl0_is_present + - query_5.ctrl1_is_present + - query_5.ctrl2_is_present + - query_5.ctrl3_is_present + - query_5.ctrl4_is_present + - query_5.ctrl5_is_present + - query_5.ctrl6_is_present + - query_5.ctrl7_is_present + - query_5.ctrl8_is_present + - query_5.ctrl9_is_present + - query_5.ctrl10_is_present + - query_5.ctrl11_is_present + - query_5.ctrl12_is_present + - query_5.ctrl13_is_present + - query_5.ctrl14_is_present + - query_5.ctrl15_is_present + - query_5.ctrl16_is_present + - query_5.ctrl17_is_present + - query_5.ctrl18_is_present + - query_5.ctrl19_is_present + - query_5.ctrl20_is_present + - query_5.ctrl21_is_present + - query_5.ctrl22_is_present; - - prox->hover_finger_en_addr = prox->control_base_addr + ctrl_23_offset; - - retval = synaptics_rmi4_reg_read(rmi4_data, - prox->query_base_addr + 8, - query_8.data, - sizeof(query_8.data)); - if (retval < 0) - return retval; - - data_1_offset = query_8.data0_is_present; - prox->hover_finger_data_addr = prox->data_base_addr + data_1_offset; - - return retval; -} - -static int prox_scan_pdt(void) -{ - int retval; - unsigned char ii; - unsigned char page; - unsigned char intr_count = 0; - unsigned char intr_off; - unsigned char intr_src; - unsigned short addr; - struct synaptics_rmi4_fn_desc fd; - struct synaptics_rmi4_data *rmi4_data = prox->rmi4_data; - - for (page = 0; page < PAGES_TO_SERVICE; page++) { - for (addr = PDT_START; addr > PDT_END; addr -= PDT_ENTRY_SIZE) { - addr |= (page << 8); - - retval = synaptics_rmi4_reg_read(rmi4_data, - addr, - (unsigned char *)&fd, - sizeof(fd)); - if (retval < 0) - return retval; - - addr &= ~(MASK_8BIT << 8); - - if (fd.fn_number) { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Found F%02x\n", - __func__, fd.fn_number); - switch (fd.fn_number) { - case SYNAPTICS_RMI4_F12: - goto f12_found; - break; - } - } else { - break; - } - - intr_count += (fd.intr_src_count & MASK_3BIT); - } - } - - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to find F12\n", - __func__); - return -EINVAL; - -f12_found: - prox->query_base_addr = fd.query_base_addr | (page << 8); - prox->control_base_addr = fd.ctrl_base_addr | (page << 8); - prox->data_base_addr = fd.data_base_addr | (page << 8); - prox->command_base_addr = fd.cmd_base_addr | (page << 8); - - retval = prox_reg_init(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to initialize proximity registers\n", - __func__); - return retval; - } - - prox->intr_mask = 0; - intr_src = fd.intr_src_count; - intr_off = intr_count % 8; - for (ii = intr_off; - ii < ((intr_src & MASK_3BIT) + - intr_off); - ii++) { - prox->intr_mask |= 1 << ii; - } - - rmi4_data->intr_mask[0] |= prox->intr_mask; - - addr = rmi4_data->f01_ctrl_base_addr + 1; - - retval = synaptics_rmi4_reg_write(rmi4_data, - addr, - &(rmi4_data->intr_mask[0]), - sizeof(rmi4_data->intr_mask[0])); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to set interrupt enable bit\n", - __func__); - return retval; - } - - return 0; -} - -static ssize_t synaptics_rmi4_hover_finger_en_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - if (!prox) - return -ENODEV; - - return snprintf(buf, PAGE_SIZE, "%u\n", - prox->hover_finger_en); -} - -static ssize_t synaptics_rmi4_hover_finger_en_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int retval; - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = prox->rmi4_data; - - if (!prox) - return -ENODEV; - - if (sscanf(buf, "%x", &input) != 1) - return -EINVAL; - - if (input == 1) - prox->hover_finger_en = true; - else if (input == 0) - prox->hover_finger_en = false; - else - return -EINVAL; - - retval = prox_set_hover_finger_en(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to change hovering finger enable setting\n", - __func__); - return retval; - } - - return count; -} - -int synaptics_rmi4_prox_hover_finger_en(bool enable) -{ - int retval; - - if (!prox) - return -ENODEV; - - prox->hover_finger_en = enable; - - retval = prox_set_hover_finger_en(); - if (retval < 0) - return retval; - - return 0; -} -EXPORT_SYMBOL(synaptics_rmi4_prox_hover_finger_en); - -static void synaptics_rmi4_prox_attn(struct synaptics_rmi4_data *rmi4_data, - unsigned char intr_mask) -{ - if (!prox) - return; - - if (prox->intr_mask & intr_mask) - prox_hover_finger_report(); - - return; -} - -static int synaptics_rmi4_prox_init(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - unsigned char attr_count; - - prox = kzalloc(sizeof(*prox), GFP_KERNEL); - if (!prox) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for prox\n", - __func__); - retval = -ENOMEM; - goto exit; - } - - prox->finger_data = kzalloc(sizeof(*(prox->finger_data)), GFP_KERNEL); - if (!prox->finger_data) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for finger_data\n", - __func__); - retval = -ENOMEM; - goto exit_free_prox; - } - - prox->rmi4_data = rmi4_data; - - retval = prox_scan_pdt(); - if (retval < 0) - goto exit_free_finger_data; - - prox->hover_finger_en = true; - - retval = prox_set_hover_finger_en(); - if (retval < 0) - return retval; - - prox->prox_dev = input_allocate_device(); - if (prox->prox_dev == NULL) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to allocate proximity device\n", - __func__); - retval = -ENOMEM; - goto exit_free_finger_data; - } - - prox->prox_dev->name = PLATFORM_DRIVER_NAME; - prox->prox_dev->phys = PROX_PHYS_NAME; - prox->prox_dev->id.product = SYNAPTICS_DSX_DRIVER_PRODUCT; - prox->prox_dev->id.version = SYNAPTICS_DSX_DRIVER_VERSION; - prox->prox_dev->dev.parent = rmi4_data->pdev->dev.parent; - input_set_drvdata(prox->prox_dev, rmi4_data); - - set_bit(EV_KEY, prox->prox_dev->evbit); - set_bit(EV_ABS, prox->prox_dev->evbit); - set_bit(BTN_TOUCH, prox->prox_dev->keybit); - set_bit(BTN_TOOL_FINGER, prox->prox_dev->keybit); -#ifdef INPUT_PROP_DIRECT - set_bit(INPUT_PROP_DIRECT, prox->prox_dev->propbit); -#endif - - prox_set_params(); - - retval = input_register_device(prox->prox_dev); - if (retval) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to register proximity device\n", - __func__); - goto exit_free_input_device; - } - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - retval = sysfs_create_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs attributes\n", - __func__); - goto exit_free_sysfs; - } - } - - return 0; - -exit_free_sysfs: - for (attr_count--; attr_count >= 0; attr_count--) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } - - input_unregister_device(prox->prox_dev); - prox->prox_dev = NULL; - -exit_free_input_device: - if (prox->prox_dev) - input_free_device(prox->prox_dev); - -exit_free_finger_data: - kfree(prox->finger_data); - -exit_free_prox: - kfree(prox); - prox = NULL; - -exit: - return retval; -} - -static void synaptics_rmi4_prox_remove(struct synaptics_rmi4_data *rmi4_data) -{ - unsigned char attr_count; - - if (!prox) - goto exit; - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - sysfs_remove_file(&rmi4_data->input_dev->dev.kobj, - &attrs[attr_count].attr); - } - - input_unregister_device(prox->prox_dev); - kfree(prox->finger_data); - kfree(prox); - prox = NULL; - -exit: - complete(&prox_remove_complete); - - return; -} - -static void synaptics_rmi4_prox_reset(struct synaptics_rmi4_data *rmi4_data) -{ - if (!prox) - return; - - prox_hover_finger_lift(); - - prox_scan_pdt(); - - prox_set_hover_finger_en(); - - prox_set_params(); - - return; -} - -static void synaptics_rmi4_prox_reinit(struct synaptics_rmi4_data *rmi4_data) -{ - if (!prox) - return; - - prox_hover_finger_lift(); - - prox_set_hover_finger_en(); - - return; -} - -static void synaptics_rmi4_prox_e_suspend(struct synaptics_rmi4_data *rmi4_data) -{ - if (!prox) - return; - - prox_hover_finger_lift(); - - return; -} - -static void synaptics_rmi4_prox_suspend(struct synaptics_rmi4_data *rmi4_data) -{ - if (!prox) - return; - - prox_hover_finger_lift(); - - return; -} - -static struct synaptics_rmi4_exp_fn proximity_module = { - .fn_type = RMI_PROXIMITY, - .init = synaptics_rmi4_prox_init, - .remove = synaptics_rmi4_prox_remove, - .reset = synaptics_rmi4_prox_reset, - .reinit = synaptics_rmi4_prox_reinit, - .early_suspend = synaptics_rmi4_prox_e_suspend, - .suspend = synaptics_rmi4_prox_suspend, - .resume = NULL, - .late_resume = NULL, - .attn = synaptics_rmi4_prox_attn, -}; - -static int __init rmi4_proximity_module_init(void) -{ - synaptics_rmi4_dsx_new_function(&proximity_module, true); - - return 0; -} - -static void __exit rmi4_proximity_module_exit(void) -{ - synaptics_rmi4_dsx_new_function(&proximity_module, false); - - wait_for_completion(&prox_remove_complete); - - return; -} - -module_init(rmi4_proximity_module_init); -module_exit(rmi4_proximity_module_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX Proximity Module"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c b/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c deleted file mode 100644 index c1cbec81d7d6..000000000000 --- a/drivers/input/touchscreen/synaptics_dsx/synaptics_dsx_rmi_dev.c +++ /dev/null @@ -1,810 +0,0 @@ -/* - * Synaptics DSX touchscreen driver - * - * Copyright (C) 2012 Synaptics Incorporated - * - * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com> - * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/input.h> -#include <linux/gpio.h> -#include <linux/uaccess.h> -#include <linux/cdev.h> -#include <linux/platform_device.h> -#include <linux/input/synaptics_dsx_v2.h> -#include "synaptics_dsx_core.h" - -#define CHAR_DEVICE_NAME "rmi" -#define DEVICE_CLASS_NAME "rmidev" -#define SYSFS_FOLDER_NAME "rmidev" -#define DEV_NUMBER 1 -#define REG_ADDR_LIMIT 0xFFFF - -static ssize_t rmidev_sysfs_data_show(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count); - -static ssize_t rmidev_sysfs_data_store(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count); - -static ssize_t rmidev_sysfs_open_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t rmidev_sysfs_release_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count); - -static ssize_t rmidev_sysfs_attn_state_show(struct device *dev, - struct device_attribute *attr, char *buf); - -struct rmidev_handle { - dev_t dev_no; - struct device dev; - struct synaptics_rmi4_data *rmi4_data; - struct kobject *sysfs_dir; - void *data; - bool irq_enabled; -}; - -struct rmidev_data { - int ref_count; - struct cdev main_dev; - struct class *device_class; - struct mutex file_mutex; - struct rmidev_handle *rmi_dev; -}; - -static struct bin_attribute attr_data = { - .attr = { - .name = "data", - .mode = (S_IRUGO | S_IWUSR), - }, - .size = 0, - .read = rmidev_sysfs_data_show, - .write = rmidev_sysfs_data_store, -}; - -static struct device_attribute attrs[] = { - __ATTR(open, S_IWUSR | S_IWGRP, - NULL, - rmidev_sysfs_open_store), - __ATTR(release, S_IWUSR | S_IWGRP, - NULL, - rmidev_sysfs_release_store), - __ATTR(attn_state, S_IRUGO, - rmidev_sysfs_attn_state_show, - synaptics_rmi4_store_error), -}; - -static int rmidev_major_num; - -static struct class *rmidev_device_class; - -static struct rmidev_handle *rmidev; - -DECLARE_COMPLETION(rmidev_remove_complete); - -static irqreturn_t rmidev_sysfs_irq(int irq, void *data) -{ - struct synaptics_rmi4_data *rmi4_data = data; - - sysfs_notify(&rmi4_data->input_dev->dev.kobj, - SYSFS_FOLDER_NAME, "attn_state"); - - return IRQ_HANDLED; -} - -static int rmidev_sysfs_irq_enable(struct synaptics_rmi4_data *rmi4_data, - bool enable) -{ - int retval = 0; - unsigned char intr_status[MAX_INTR_REGISTERS]; - unsigned long irq_flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING; - - if (enable) { - if (rmidev->irq_enabled) - return retval; - - /* Clear interrupts first */ - retval = synaptics_rmi4_reg_read(rmi4_data, - rmi4_data->f01_data_base_addr + 1, - intr_status, - rmi4_data->num_of_intr_regs); - if (retval < 0) - return retval; - - retval = request_threaded_irq(rmi4_data->irq, NULL, - rmidev_sysfs_irq, irq_flags, - "synaptics_dsx_rmidev", rmi4_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create irq thread\n", - __func__); - return retval; - } - - rmidev->irq_enabled = true; - } else { - if (rmidev->irq_enabled) { - disable_irq(rmi4_data->irq); - free_irq(rmi4_data->irq, rmi4_data); - rmidev->irq_enabled = false; - } - } - - return retval; -} - -static ssize_t rmidev_sysfs_data_show(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count) -{ - int retval; - unsigned int length = (unsigned int)count; - unsigned short address = (unsigned short)pos; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - - if (length > (REG_ADDR_LIMIT - address)) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Out of register map limit\n", - __func__); - return -EINVAL; - } - - if (length) { - retval = synaptics_rmi4_reg_read(rmi4_data, - address, - (unsigned char *)buf, - length); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to read data\n", - __func__); - return retval; - } - } else { - return -EINVAL; - } - - return length; -} - -static ssize_t rmidev_sysfs_data_store(struct file *data_file, - struct kobject *kobj, struct bin_attribute *attributes, - char *buf, loff_t pos, size_t count) -{ - int retval; - unsigned int length = (unsigned int)count; - unsigned short address = (unsigned short)pos; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - - if (length > (REG_ADDR_LIMIT - address)) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Out of register map limit\n", - __func__); - return -EINVAL; - } - - if (length) { - retval = synaptics_rmi4_reg_write(rmi4_data, - address, - (unsigned char *)buf, - length); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to write data\n", - __func__); - return retval; - } - } else { - return -EINVAL; - } - - return length; -} - -static ssize_t rmidev_sysfs_open_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input != 1) - return -EINVAL; - - rmi4_data->irq_enable(rmi4_data, false); - rmidev_sysfs_irq_enable(rmi4_data, true); - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Attention interrupt disabled\n", - __func__); - - return count; -} - -static ssize_t rmidev_sysfs_release_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned int input; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - - if (sscanf(buf, "%u", &input) != 1) - return -EINVAL; - - if (input != 1) - return -EINVAL; - - rmi4_data->reset_device(rmi4_data); - - rmidev_sysfs_irq_enable(rmi4_data, false); - rmi4_data->irq_enable(rmi4_data, true); - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Attention interrupt enabled\n", - __func__); - - return count; -} - -static ssize_t rmidev_sysfs_attn_state_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int attn_state; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - attn_state = gpio_get_value(bdata->irq_gpio); - - return snprintf(buf, PAGE_SIZE, "%u\n", attn_state); -} - -/* - * rmidev_llseek - used to set up register address - * - * @filp: file structure for seek - * @off: offset - * if whence == SEEK_SET, - * high 16 bits: page address - * low 16 bits: register address - * if whence == SEEK_CUR, - * offset from current position - * if whence == SEEK_END, - * offset from end position (0xFFFF) - * @whence: SEEK_SET, SEEK_CUR, or SEEK_END - */ -static loff_t rmidev_llseek(struct file *filp, loff_t off, int whence) -{ - loff_t newpos; - struct rmidev_data *dev_data = filp->private_data; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - - if (IS_ERR(dev_data)) { - pr_err("%s: Pointer of char device data is invalid", __func__); - return -EBADF; - } - - mutex_lock(&(dev_data->file_mutex)); - - switch (whence) { - case SEEK_SET: - newpos = off; - break; - case SEEK_CUR: - newpos = filp->f_pos + off; - break; - case SEEK_END: - newpos = REG_ADDR_LIMIT + off; - break; - default: - newpos = -EINVAL; - goto clean_up; - } - - if (newpos < 0 || newpos > REG_ADDR_LIMIT) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: New position 0x%04x is invalid\n", - __func__, (unsigned int)newpos); - newpos = -EINVAL; - goto clean_up; - } - - filp->f_pos = newpos; - -clean_up: - mutex_unlock(&(dev_data->file_mutex)); - - return newpos; -} - -/* - * rmidev_read: - use to read data from rmi device - * - * @filp: file structure for read - * @buf: user space buffer pointer - * @count: number of bytes to read - * @f_pos: offset (starting register address) - */ -static ssize_t rmidev_read(struct file *filp, char __user *buf, - size_t count, loff_t *f_pos) -{ - ssize_t retval; - unsigned char *tmpbuf; - struct rmidev_data *dev_data = filp->private_data; - - if (IS_ERR(dev_data)) { - pr_err("%s: Pointer of char device data is invalid", __func__); - return -EBADF; - } - - mutex_lock(&(dev_data->file_mutex)); - - if (count > (REG_ADDR_LIMIT - *f_pos)) - count = REG_ADDR_LIMIT - *f_pos; - - if (count == 0) { - retval = 0; - goto unlock; - } - - if (*f_pos > REG_ADDR_LIMIT) { - retval = -EFAULT; - goto unlock; - } - tmpbuf = kzalloc(count + 1, GFP_KERNEL); - if (!tmpbuf) { - retval = -ENOMEM; - goto unlock; - } - retval = synaptics_rmi4_reg_read(rmidev->rmi4_data, - *f_pos, - tmpbuf, - count); - if (retval < 0) - goto clean_up; - - if (copy_to_user(buf, tmpbuf, count)) - retval = -EFAULT; - else - *f_pos += retval; - -clean_up: - kfree(tmpbuf); -unlock: - mutex_unlock(&(dev_data->file_mutex)); - return retval; -} - -/* - * rmidev_write: - used to write data to rmi device - * - * @filep: file structure for write - * @buf: user space buffer pointer - * @count: number of bytes to write - * @f_pos: offset (starting register address) - */ -static ssize_t rmidev_write(struct file *filp, const char __user *buf, - size_t count, loff_t *f_pos) -{ - ssize_t retval; - unsigned char *tmpbuf; - struct rmidev_data *dev_data = filp->private_data; - - if (IS_ERR(dev_data)) { - pr_err("%s: Pointer of char device data is invalid", __func__); - return -EBADF; - } - - mutex_lock(&(dev_data->file_mutex)); - - if (*f_pos > REG_ADDR_LIMIT) { - retval = -EFAULT; - goto unlock; - } - - if (count > (REG_ADDR_LIMIT - *f_pos)) - count = REG_ADDR_LIMIT - *f_pos; - - if (count == 0) { - retval = 0; - goto unlock; - } - - tmpbuf = kzalloc(count + 1, GFP_KERNEL); - if (!tmpbuf) { - retval = -ENOMEM; - goto unlock; - } - - if (copy_from_user(tmpbuf, buf, count)) { - retval = -EFAULT; - goto clean_up; - } - - retval = synaptics_rmi4_reg_write(rmidev->rmi4_data, - *f_pos, - tmpbuf, - count); - if (retval >= 0) - *f_pos += retval; - -clean_up: - kfree(tmpbuf); -unlock: - mutex_unlock(&(dev_data->file_mutex)); - return retval; -} - -/* - * rmidev_open: enable access to rmi device - * @inp: inode struture - * @filp: file structure - */ -static int rmidev_open(struct inode *inp, struct file *filp) -{ - int retval = 0; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - struct rmidev_data *dev_data = - container_of(inp->i_cdev, struct rmidev_data, main_dev); - - if (!dev_data) - return -EACCES; - - filp->private_data = dev_data; - - mutex_lock(&(dev_data->file_mutex)); - - rmi4_data->irq_enable(rmi4_data, false); - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Attention interrupt disabled\n", - __func__); - - if (dev_data->ref_count < 1) - dev_data->ref_count++; - else - retval = -EACCES; - - mutex_unlock(&(dev_data->file_mutex)); - - return retval; -} - -/* - * rmidev_release: - release access to rmi device - * @inp: inode structure - * @filp: file structure - */ -static int rmidev_release(struct inode *inp, struct file *filp) -{ - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - struct rmidev_data *dev_data = - container_of(inp->i_cdev, struct rmidev_data, main_dev); - - if (!dev_data) - return -EACCES; - - rmi4_data->reset_device(rmi4_data); - - mutex_lock(&(dev_data->file_mutex)); - - dev_data->ref_count--; - if (dev_data->ref_count < 0) - dev_data->ref_count = 0; - - rmi4_data->irq_enable(rmi4_data, true); - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Attention interrupt enabled\n", - __func__); - - mutex_unlock(&(dev_data->file_mutex)); - - return 0; -} - -static const struct file_operations rmidev_fops = { - .owner = THIS_MODULE, - .llseek = rmidev_llseek, - .read = rmidev_read, - .write = rmidev_write, - .open = rmidev_open, - .release = rmidev_release, -}; - -static void rmidev_device_cleanup(struct rmidev_data *dev_data) -{ - dev_t devno; - struct synaptics_rmi4_data *rmi4_data = rmidev->rmi4_data; - - if (dev_data) { - devno = dev_data->main_dev.dev; - - if (dev_data->device_class) - device_destroy(dev_data->device_class, devno); - - cdev_del(&dev_data->main_dev); - - unregister_chrdev_region(devno, 1); - - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: rmidev device removed\n", - __func__); - } - - return; -} - -static char *rmi_char_devnode(struct device *dev, umode_t *mode) -{ - if (!mode) - return NULL; - - *mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - - return kasprintf(GFP_KERNEL, "rmi/%s", dev_name(dev)); -} - -static int rmidev_create_device_class(void) -{ - rmidev_device_class = class_create(THIS_MODULE, DEVICE_CLASS_NAME); - - if (IS_ERR(rmidev_device_class)) { - pr_err("%s: Failed to create /dev/%s\n", - __func__, CHAR_DEVICE_NAME); - return -ENODEV; - } - - rmidev_device_class->devnode = rmi_char_devnode; - - return 0; -} - -static int rmidev_init_device(struct synaptics_rmi4_data *rmi4_data) -{ - int retval; - dev_t dev_no; - unsigned char attr_count; - struct rmidev_data *dev_data; - struct device *device_ptr; - const struct synaptics_dsx_board_data *bdata = - rmi4_data->hw_if->board_data; - - rmidev = kzalloc(sizeof(*rmidev), GFP_KERNEL); - if (!rmidev) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for rmidev\n", - __func__); - retval = -ENOMEM; - goto err_rmidev; - } - - rmidev->rmi4_data = rmi4_data; - - retval = rmidev_create_device_class(); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create device class\n", - __func__); - goto err_device_class; - } - - if (rmidev_major_num) { - dev_no = MKDEV(rmidev_major_num, DEV_NUMBER); - retval = register_chrdev_region(dev_no, 1, CHAR_DEVICE_NAME); - } else { - retval = alloc_chrdev_region(&dev_no, 0, 1, CHAR_DEVICE_NAME); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to allocate char device region\n", - __func__); - goto err_device_region; - } - - rmidev_major_num = MAJOR(dev_no); - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Major number of rmidev = %d\n", - __func__, rmidev_major_num); - } - - dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL); - if (!dev_data) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to alloc mem for dev_data\n", - __func__); - retval = -ENOMEM; - goto err_dev_data; - } - - mutex_init(&dev_data->file_mutex); - dev_data->rmi_dev = rmidev; - rmidev->data = dev_data; - - cdev_init(&dev_data->main_dev, &rmidev_fops); - - retval = cdev_add(&dev_data->main_dev, dev_no, 1); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to add rmi char device\n", - __func__); - goto err_char_device; - } - - dev_set_name(&rmidev->dev, "rmidev%d", MINOR(dev_no)); - dev_data->device_class = rmidev_device_class; - - device_ptr = device_create(dev_data->device_class, NULL, dev_no, - NULL, CHAR_DEVICE_NAME"%d", MINOR(dev_no)); - if (IS_ERR(device_ptr)) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create rmi char device\n", - __func__); - retval = -ENODEV; - goto err_char_device; - } - - retval = gpio_export(bdata->irq_gpio, false); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to export attention gpio\n", - __func__); - } else { - retval = gpio_export_link(&(rmi4_data->input_dev->dev), - "attn", bdata->irq_gpio); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s Failed to create gpio symlink\n", - __func__); - } else { - dev_dbg(rmi4_data->pdev->dev.parent, - "%s: Exported attention gpio %d\n", - __func__, bdata->irq_gpio); - } - } - - rmidev->sysfs_dir = kobject_create_and_add(SYSFS_FOLDER_NAME, - &rmi4_data->input_dev->dev.kobj); - if (!rmidev->sysfs_dir) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs directory\n", - __func__); - retval = -ENODEV; - goto err_sysfs_dir; - } - - retval = sysfs_create_bin_file(rmidev->sysfs_dir, - &attr_data); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs bin file\n", - __func__); - goto err_sysfs_bin; - } - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) { - retval = sysfs_create_file(rmidev->sysfs_dir, - &attrs[attr_count].attr); - if (retval < 0) { - dev_err(rmi4_data->pdev->dev.parent, - "%s: Failed to create sysfs attributes\n", - __func__); - retval = -ENODEV; - goto err_sysfs_attrs; - } - } - - return 0; - -err_sysfs_attrs: - for (attr_count--; attr_count >= 0; attr_count--) - sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr); - - sysfs_remove_bin_file(rmidev->sysfs_dir, &attr_data); - -err_sysfs_bin: - kobject_put(rmidev->sysfs_dir); - -err_sysfs_dir: -err_char_device: - rmidev_device_cleanup(dev_data); - kfree(dev_data); - -err_dev_data: - unregister_chrdev_region(dev_no, 1); - -err_device_region: - class_destroy(rmidev_device_class); - -err_device_class: - kfree(rmidev); - rmidev = NULL; - -err_rmidev: - return retval; -} - -static void rmidev_remove_device(struct synaptics_rmi4_data *rmi4_data) -{ - unsigned char attr_count; - struct rmidev_data *dev_data; - - if (!rmidev) - goto exit; - - for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) - sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr); - - sysfs_remove_bin_file(rmidev->sysfs_dir, &attr_data); - - kobject_put(rmidev->sysfs_dir); - - dev_data = rmidev->data; - if (dev_data) { - rmidev_device_cleanup(dev_data); - kfree(dev_data); - } - - unregister_chrdev_region(rmidev->dev_no, 1); - - class_destroy(rmidev_device_class); - - kfree(rmidev); - rmidev = NULL; - -exit: - complete(&rmidev_remove_complete); - - return; -} - -static struct synaptics_rmi4_exp_fn rmidev_module = { - .fn_type = RMI_DEV, - .init = rmidev_init_device, - .remove = rmidev_remove_device, - .reset = NULL, - .reinit = NULL, - .early_suspend = NULL, - .suspend = NULL, - .resume = NULL, - .late_resume = NULL, - .attn = NULL, -}; - -static int __init rmidev_module_init(void) -{ - synaptics_rmi4_dsx_new_function(&rmidev_module, true); - - return 0; -} - -static void __exit rmidev_module_exit(void) -{ - synaptics_rmi4_dsx_new_function(&rmidev_module, false); - - wait_for_completion(&rmidev_remove_complete); - - return; -} - -module_init(rmidev_module_init); -module_exit(rmidev_module_exit); - -MODULE_AUTHOR("Synaptics, Inc."); -MODULE_DESCRIPTION("Synaptics DSX RMI Dev Module"); -MODULE_LICENSE("GPL v2"); |