mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
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 <jinrong.liao@amlogic.com>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
cy8c4014_08: cy8c4014_08@08 {
|
||||
compatible = "cy8c4014";
|
||||
#sound-dai-cells = <0>;
|
||||
reg = <0x8>;
|
||||
status = "okay";
|
||||
};
|
||||
@@ -14618,3 +14618,5 @@ AMLOGIC SYSTEM AS ROOT
|
||||
M: Renjun Xu <renjun.xu@amlogic.com>
|
||||
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
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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/
|
||||
|
||||
21
drivers/amlogic/input/sensor/Kconfig
Normal file
21
drivers/amlogic/input/sensor/Kconfig
Normal file
@@ -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
|
||||
5
drivers/amlogic/input/sensor/Makefile
Normal file
5
drivers/amlogic/input/sensor/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
#
|
||||
# Makefile for the sensor drivers.
|
||||
#
|
||||
obj-$(CONFIG_AMLOGIC_SENSOR_CY8C4014) += cy8c4014.o
|
||||
|
||||
330
drivers/amlogic/input/sensor/cy8c4014.c
Normal file
330
drivers/amlogic/input/sensor/cy8c4014.c
Normal file
@@ -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 <linux/sched.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user