From: jinrong.liao Date: Wed, 29 Aug 2018 04:21:49 +0000 (+0800) Subject: input: add touch sensor driver. X-Git-Tag: khadas-vims-v0.9.6-release~1479 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a4625c4ac3bd79abc87d1cc72faf00d6532e0366;p=platform%2Fkernel%2Flinux-amlogic.git input: add touch sensor driver. PD#172287: this commit changes mainly for GVA 1) add sensor cy8c4014 driver. Change-Id: Ic1ed6cf2a42e2286e4860946d89091a3dd524ef8 Signed-off-by: jinrong.liao --- diff --git a/Documentation/devicetree/bindings/amlogic/input/cy8c4014_i2c.txt b/Documentation/devicetree/bindings/amlogic/input/cy8c4014_i2c.txt new file mode 100644 index 0000000..20c5222 --- /dev/null +++ b/Documentation/devicetree/bindings/amlogic/input/cy8c4014_i2c.txt @@ -0,0 +1,6 @@ +cy8c4014_08: cy8c4014_08@08 { + compatible = "cy8c4014"; + #sound-dai-cells = <0>; + reg = <0x8>; + status = "okay"; +}; diff --git a/MAINTAINERS b/MAINTAINERS index 37cb69b..e5bf092 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14618,3 +14618,5 @@ AMLOGIC SYSTEM AS ROOT M: Renjun Xu F: arch/arm64/boot/dts/amlogic/axg_s400_v03gva.dts F: arch/arm64/boot/dts/amlogic/axg_s420_v03gva.dts +F: Documentation/devicetree/bindings/input/cy8c4014_i2c.txt +F: drivers/amlogic/input/sensor/cy8c4014.c diff --git a/arch/arm64/boot/dts/amlogic/axg_s400_v03gva.dts b/arch/arm64/boot/dts/amlogic/axg_s400_v03gva.dts index 7d76763..c9311bf 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400_v03gva.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400_v03gva.dts @@ -983,6 +983,12 @@ reg = <0x13>; status = "disable"; }; + cy8c4014_08: cy8c4014_08@08 { + compatible = "cy8c4014"; + #sound-dai-cells = <0>; + reg = <0x8>; + status = "okay"; + }; is31fl3236a: is31f3236a@0x78 { compatible = "issi,is31fl3236"; reg = <0x3c>; diff --git a/arch/arm64/boot/dts/amlogic/axg_s420_v03gva.dts b/arch/arm64/boot/dts/amlogic/axg_s420_v03gva.dts index 9ec2416d..f55e35e 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s420_v03gva.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s420_v03gva.dts @@ -803,6 +803,12 @@ reg = <0x13>; status = "disable"; }; + cy8c4014_08: cy8c4014_08@08 { + compatible = "cy8c4014"; + #sound-dai-cells = <0>; + reg = <0x8>; + status = "okay"; + }; is31fl3236a: is31f3236a@0x78 { compatible = "issi,is31fl3236"; reg = <0x3c>; diff --git a/arch/arm64/configs/meson64_smarthome_defconfig b/arch/arm64/configs/meson64_smarthome_defconfig index 51760ad..46fe2d4 100644 --- a/arch/arm64/configs/meson64_smarthome_defconfig +++ b/arch/arm64/configs/meson64_smarthome_defconfig @@ -311,6 +311,8 @@ CONFIG_AMLOGIC_IIO=y CONFIG_AMLOGIC_SARADC=y CONFIG_AMLOGIC_DDR_WINDOW_TOOL=m CONFIG_AMLOGIC_LEDRING=y +CONFIG_AMLOGIC_SENSOR=y +CONFIG_AMLOGIC_SENSOR_CY8C4014=y CONFIG_AMLOGIC_GPIO_IRQ=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y diff --git a/drivers/amlogic/input/Kconfig b/drivers/amlogic/input/Kconfig index 5e0685b..47317b0 100644 --- a/drivers/amlogic/input/Kconfig +++ b/drivers/amlogic/input/Kconfig @@ -17,5 +17,8 @@ source "drivers/amlogic/input/keyboard/Kconfig" source "drivers/amlogic/input/remote/Kconfig" source "drivers/amlogic/input/touchscreen/Kconfig" + +source "drivers/amlogic/input/sensor/Kconfig" + endif diff --git a/drivers/amlogic/input/Makefile b/drivers/amlogic/input/Makefile index ae6f8ab..3ea361c 100644 --- a/drivers/amlogic/input/Makefile +++ b/drivers/amlogic/input/Makefile @@ -11,3 +11,5 @@ obj-$(CONFIG_AMLOGIC_INPUT_KEYBOARD) += keyboard/ obj-$(CONFIG_AMLOGIC_REMOTE) += remote/ obj-$(CONFIG_AMLOGIC_TOUCHSCREEN) += touchscreen/ + +obj-$(CONFIG_AMLOGIC_SENSOR) += sensor/ diff --git a/drivers/amlogic/input/sensor/Kconfig b/drivers/amlogic/input/sensor/Kconfig new file mode 100644 index 0000000..f0f4214 --- /dev/null +++ b/drivers/amlogic/input/sensor/Kconfig @@ -0,0 +1,21 @@ +menuconfig AMLOGIC_SENSOR + bool "Sensor devices" + ---help--- + Say Y here to get to see options for sensor device drivers from + all categories. This option alone does not add any kernel code. + + If you say N,all options in this submenu will be skipped and disabled. + +if AMLOGIC_SENSOR + +config AMLOGIC_SENSOR_CY8C4014 + tristate "cy8c4014 sensor driver" + depends on I2C + default n + help + Say yes here to support Cypress cy8c4014 sensor and proximity + sensor + Say yes here to support Cypress cy8c4014 sensor and proximity + sensor + +endif # SENSOR_DEVICES diff --git a/drivers/amlogic/input/sensor/Makefile b/drivers/amlogic/input/sensor/Makefile new file mode 100644 index 0000000..51c18f9 --- /dev/null +++ b/drivers/amlogic/input/sensor/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the sensor drivers. +# +obj-$(CONFIG_AMLOGIC_SENSOR_CY8C4014) += cy8c4014.o + diff --git a/drivers/amlogic/input/sensor/cy8c4014.c b/drivers/amlogic/input/sensor/cy8c4014.c new file mode 100644 index 0000000..d1600b4 --- /dev/null +++ b/drivers/amlogic/input/sensor/cy8c4014.c @@ -0,0 +1,330 @@ +/* + * drivers/amlogic/input/sensor/cy8c4014.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define DRV_VERSION "1.0.0.0" +#define CY8C4014_DEV_NAME "cy8c4014" +#define CY8C4014_SCHE_DELAY 200 +#define CY8C4014_ADDR 0x8 + +struct cy8c4014_data { + struct delayed_work work; + struct input_dev *input_dev; + struct i2c_client *i2c_client; + int delay; + int enable; + struct mutex mutex; +}; +struct cy8c4014_data *cy8c4014_data; +static struct i2c_driver cy8c4014_driver; + +static int cy8c4014_reset(struct i2c_client *client) +{ + return 0; +} + +int cy8c4014_read(struct i2c_client *dev, int add, uint8_t *val) +{ + int ret; + uint8_t buf[2] = {}; + struct i2c_msg msg[] = { + { + .addr = CY8C4014_ADDR, + .flags = 0, + .len = sizeof(buf), + .buf = buf, + }, + { + .addr = CY8C4014_ADDR, + .flags = I2C_M_RD, + .len = 1, + .buf = val, + } + }; + + + buf[0] = add & 0xff; + buf[1] = (add >> 8) & 0x0f; + ret = i2c_transfer(dev->adapter, msg, 2); + if (ret < 0) { + pr_info("%s: i2c transfer failed, ret:%d\n", __func__, ret); + return ret; + } + return 0; +} + +static void cy8c4014_schedwork(struct work_struct *work) +{ + unsigned long delay = msecs_to_jiffies(cy8c4014_data->delay); + struct input_dev *input_dev = cy8c4014_data->input_dev; + uint8_t x = 0; + /*uint8_t y = 0;*/ + + cy8c4014_read(cy8c4014_data->i2c_client, 0x00, &x); + /*cy8c4014_read(cy8c4014_data->i2c_client,0x01,&y);*/ + if (x != 0xFF) + input_report_abs(input_dev, ABS_X, x); + /*if(y != 0xFF)*/ + /*input_report_abs(input_dev, ABS_Y, y);*/ + input_sync(input_dev); + schedule_delayed_work(&cy8c4014_data->work, delay); +} + +static ssize_t cy8c4014_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = 0; + + ret = sprintf(buf, "cy8c4014 sensor Auto Enable = %d\n", + cy8c4014_data->enable); + + return ret; +} + +static int cy8c4014_sensor_enable(void) +{ + int ret = 0; + + unsigned long delay = msecs_to_jiffies(cy8c4014_data->delay); + + if (cy8c4014_data->enable == 1) + return ret; + + mutex_lock(&cy8c4014_data->mutex); + + schedule_delayed_work(&cy8c4014_data->work, delay); + cy8c4014_data->enable = 1; + + mutex_unlock(&cy8c4014_data->mutex); + + return ret; +} + +static int cy8c4014_sensor_disable(void) +{ + int ret = 0; + + if (cy8c4014_data->enable == 0) + return ret; + + mutex_lock(&cy8c4014_data->mutex); + + cancel_delayed_work(&cy8c4014_data->work); + cy8c4014_data->enable = 0; + + mutex_unlock(&cy8c4014_data->mutex); + + return ret; +} +static ssize_t cy8c4014_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ls_auto, ret; + + ls_auto = -1; + ret = kstrtoint(buf, 10, &ls_auto); + if (ret == -1) + return -EINVAL; + if (ls_auto != 0 && ls_auto != 1) + return -EINVAL; + + if (ls_auto) + cy8c4014_sensor_enable(); + else + cy8c4014_sensor_disable(); + + + return count; +} + +static ssize_t cy8c4014_poll_delay_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = 0; + + ret = sprintf(buf, "cy8c4014 sensor Poll Delay = %d ms\n", + cy8c4014_data->delay); + + return ret; +} + +static ssize_t cy8c4014_poll_delay_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int new_delay, ret; + + ret = kstrtoint(buf, 10, &new_delay); + if (ret == -1) + return -EINVAL; + pr_info("new delay = %d ms, old delay = %d ms\n", new_delay, + cy8c4014_data->delay); + + cy8c4014_data->delay = new_delay; + + if (cy8c4014_data->enable) { + cy8c4014_sensor_disable(); + cy8c4014_sensor_enable(); + } + + return count; +} + +static struct device_attribute dev_attr_cy8c4014_enable = +__ATTR(enable, 0664, cy8c4014_enable_show, + cy8c4014_enable_store); + +static struct device_attribute dev_attr_cy8c4014_delay = +__ATTR(delay, 0664, cy8c4014_poll_delay_show, + cy8c4014_poll_delay_store); + +static struct attribute *sensor_sysfs_attrs[] = { +&dev_attr_cy8c4014_enable.attr, +&dev_attr_cy8c4014_delay.attr, +NULL +}; + +static struct attribute_group cy8c4014_attribute_group = { +.attrs = sensor_sysfs_attrs, +}; + +static int cy8c4014_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0; + struct input_dev *idev; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + + pr_info(" start cy8c4014 probe !!\n"); + + if (!i2c_check_functionality(adapter, + I2C_FUNC_SMBUS_WRITE_BYTE | I2C_FUNC_SMBUS_READ_BYTE_DATA)){ + ret = -EIO; + return ret; + } + + /* data memory allocation */ + cy8c4014_data = kzalloc(sizeof(struct cy8c4014_data), GFP_KERNEL); + if (cy8c4014_data == NULL) { + ret = -ENOMEM; + return ret; + } + cy8c4014_data->i2c_client = client; + + i2c_set_clientdata(client, cy8c4014_data); + + cy8c4014_reset(cy8c4014_data->i2c_client); + + INIT_DELAYED_WORK(&cy8c4014_data->work, cy8c4014_schedwork); + cy8c4014_data->delay = CY8C4014_SCHE_DELAY; + + idev = input_allocate_device(); + if (!idev) { + pr_alert("%s: cy8c4014 allocate input device failed.\n", + __func__); + goto kfree_exit; + } + + idev->name = CY8C4014_DEV_NAME; + idev->id.bustype = BUS_I2C; + input_set_capability(idev, EV_ABS, ABS_X); + input_set_capability(idev, EV_ABS, ABS_Y); + input_set_abs_params(idev, ABS_X, 0, 255, 0, 0); + input_set_abs_params(idev, ABS_Y, 0, 255, 0, 0); + cy8c4014_data->input_dev = idev; + input_set_drvdata(idev, cy8c4014_data); + + ret = input_register_device(idev); + if (ret < 0) { + input_free_device(idev); + goto kfree_exit; + } + + mutex_init(&cy8c4014_data->mutex); + /* register the attributes */ + ret = sysfs_create_group(&idev->dev.kobj, &cy8c4014_attribute_group); + if (ret) + goto unregister_exit; + + schedule_delayed_work(&cy8c4014_data->work, CY8C4014_SCHE_DELAY); + cy8c4014_data->enable = 1; + return ret; + +unregister_exit: + input_unregister_device(idev); + input_free_device(idev); + +kfree_exit: + kfree(cy8c4014_data); + return ret; +} + +static int cy8c4014_remove(struct i2c_client *client) +{ + i2c_unregister_device(cy8c4014_data->i2c_client); + cancel_delayed_work(&cy8c4014_data->work); + kfree(cy8c4014_data); + return 0; +} +static const struct i2c_device_id cy8c4014_id[] = { + { CY8C4014_DEV_NAME, 0 }, + { } +}; + +static struct i2c_driver cy8c4014_driver = { + .driver = { + .name = CY8C4014_DEV_NAME, + .owner = THIS_MODULE, + }, + .probe = cy8c4014_probe, + .remove = cy8c4014_remove, + .id_table = cy8c4014_id, +}; + +static int __init cy8c4014_init(void) +{ + i2c_add_driver(&cy8c4014_driver); + return 0; +} + +static void __exit cy8c4014_exit(void) +{ + i2c_del_driver(&cy8c4014_driver); +} + +module_init(cy8c4014_init); +module_exit(cy8c4014_exit); + +MODULE_AUTHOR("Amlogic"); +MODULE_DESCRIPTION("CYPRESS CY8C4014 driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); + diff --git a/drivers/amlogic/ledring/aml-pca9557.c b/drivers/amlogic/ledring/aml-pca9557.c index 59cc6d0..53efaf1 100644 --- a/drivers/amlogic/ledring/aml-pca9557.c +++ b/drivers/amlogic/ledring/aml-pca9557.c @@ -74,7 +74,7 @@ static struct _key_led { int mode; } *key_led_des; -struct _key_des { +static struct _key_des { char name[MAX_NAME_LEN]; unsigned int key_val; int pin;