summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMukund Navada Kanyana2021-02-04 01:03:22 -0600
committerMukund Navada Kanyana2021-02-04 01:03:22 -0600
commitb0c709e6328dcb778a82beba5a2a27c2987a7476 (patch)
treeefa5d40f31b6e2a378fd0488963663f9b64a8106
parent6df61bc36a0c6580e77c25c28b64faf5114b2cf0 (diff)
downloaddrv260x-util-b0c709e6328dcb778a82beba5a2a27c2987a7476.tar.gz
drv260x-util-b0c709e6328dcb778a82beba5a2a27c2987a7476.tar.xz
drv260x-util-b0c709e6328dcb778a82beba5a2a27c2987a7476.zip
Add support for DRV2603 Timedout architecture supportHEADmaster
-rw-r--r--drv2603/Makefile2
-rw-r--r--drv2603/Readme.txt6
-rw-r--r--drv2603/drv2603.c154
-rw-r--r--drv2603/dts.readme4
-rw-r--r--drv2603/timed_output.c126
-rw-r--r--drv2603/timed_output.h37
6 files changed, 329 insertions, 0 deletions
diff --git a/drv2603/Makefile b/drv2603/Makefile
new file mode 100644
index 0000000..bc64262
--- /dev/null
+++ b/drv2603/Makefile
@@ -0,0 +1,2 @@
1obj-y += drv2603.o
2obj-y += timed_output.o
diff --git a/drv2603/Readme.txt b/drv2603/Readme.txt
new file mode 100644
index 0000000..3e71579
--- /dev/null
+++ b/drv2603/Readme.txt
@@ -0,0 +1,6 @@
1/***** drv2603 driver Discription *****/
2
31.This code only creates the timedout architecture for drv2603.
4 Add an activate node into it
5
62.The specific features should be implemented by the customer \ No newline at end of file
diff --git a/drv2603/drv2603.c b/drv2603/drv2603.c
new file mode 100644
index 0000000..e729dce
--- /dev/null
+++ b/drv2603/drv2603.c
@@ -0,0 +1,154 @@
1/* ************************************************************************
2 * Filename: drv2603.c
3 * Description:
4 * Version: 1.0
5 * Created: 05/08/2020 03:53:39 PM
6 * Revision: none
7 * Compiler: gcc
8 * Author: YOUR NAME (),
9 * Company:
10 * ************************************************************************/
11
12#define DEBUG
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/slab.h>
17#include <linux/types.h>
18#include <linux/fs.h>
19#include <linux/semaphore.h>
20#include <linux/device.h>
21#include <linux/syscalls.h>
22#include <asm/uaccess.h>
23#include <linux/gpio.h>
24#include <linux/sched.h>
25#include <linux/spinlock_types.h>
26#include <linux/spinlock.h>
27#include <linux/delay.h>
28#include <linux/of.h>
29#include <linux/of_gpio.h>
30#include <linux/jiffies.h>
31#include <linux/err.h>
32#include <linux/clk.h>
33#include <linux/miscdevice.h>
34#include <linux/interrupt.h>
35#include <linux/cdev.h>
36#include "timed_output.h"
37struct drv2603_data {
38 struct mutex lock;
39 struct mutex dev_lock;
40 struct cdev cdev;
41 struct hrtimer haptics_timer;
42 struct timed_output_dev to_dev;
43};
44static int vibrator_get_time(struct timed_output_dev *dev)
45{
46 struct drv2603_data *pDRV2603 =
47 container_of(dev, struct drv2603_data, to_dev);
48 if (hrtimer_active(&pDRV2603->haptics_timer)) {
49 ktime_t r = hrtimer_get_remaining(&pDRV2603->haptics_timer);
50 return ktime_to_ms(r);
51 }
52 return 0;
53}
54
55static void vibrator_enable(struct timed_output_dev *dev, int value)
56{
57 struct drv2603_data *pDRV2603 = container_of(dev, struct drv2603_data, to_dev);
58 dev_err(pDRV2603->to_dev.dev, "%s, value=%d\n", __func__, value);
59}
60
61static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
62{
63 struct drv2603_data *pDRV2603 =
64 container_of(timer, struct drv2603_data, haptics_timer);
65 dev_err(pDRV2603->to_dev.dev, "%s\n", __func__);
66 return HRTIMER_NORESTART;
67}
68
69static ssize_t drv2603_activate_store(struct device *dev, struct device_attribute *attr,
70 const char *buf, size_t size)
71{
72 struct timed_output_dev *timed_dev = dev_get_drvdata(dev);
73 struct drv2603_data *pDRV2603 = container_of(timed_dev, struct drv2603_data, to_dev);
74 dev_err(pDRV2603->to_dev.dev,"%s:enter!\n", __func__);
75 return size;
76}
77static ssize_t drv2603_activate_show(struct device *dev, struct device_attribute *attr, char *buf)
78{
79 struct timed_output_dev *timed_dev = dev_get_drvdata(dev);
80 struct drv2603_data *pDRV2603 = container_of(timed_dev, struct drv2603_data, to_dev);
81 dev_err(pDRV2603->to_dev.dev,"%s:enter!\n", __func__);
82 return 0;
83
84}
85static DEVICE_ATTR(activate, 0664, drv2603_activate_show, drv2603_activate_store);
86static struct attribute *drv2603_vibrator_attributes[] = {
87 &dev_attr_activate.attr,
88 NULL
89};
90
91static struct attribute_group drv2603_vibrator_attribute_group = {
92 .attrs = drv2603_vibrator_attributes
93};
94
95static int Haptics_init(struct drv2603_data *pDRV2603)
96{
97 int nResult = 0;
98 printk("%s,%d\n",__func__,__LINE__);
99 pDRV2603->to_dev.name = "vibrator";
100 pDRV2603->to_dev.get_time = vibrator_get_time;
101 pDRV2603->to_dev.enable = vibrator_enable;
102 nResult = timed_output_dev_register(&(pDRV2603->to_dev));
103 if (nResult < 0) {
104 dev_err(pDRV2603->to_dev.dev,
105 "drv2603: fail to create timed output dev\n");
106 return nResult;
107 }
108 hrtimer_init(&pDRV2603->haptics_timer, CLOCK_MONOTONIC,
109 HRTIMER_MODE_REL);
110 pDRV2603->haptics_timer.function = vibrator_timer_func;
111
112 mutex_init(&pDRV2603->lock);
113 return 0;
114}
115static int drv2603_parse_dt(struct drv2603_data *pDRV2603)
116{
117 struct device_node *cgnp;
118 int nResult = 0;
119 printk("%s:enter!\n", __func__);
120 cgnp = of_find_compatible_node(NULL, NULL, "ti_tas2603");
121 nResult = of_get_named_gpio(cgnp, "ti,reset-gpio", 0);
122 dev_err(pDRV2603->to_dev.dev, "%s:ti,reset-gpio=%d\n", __func__, nResult);
123 return nResult;
124}
125int drv2603_init(void)
126{
127 struct drv2603_data *pDRV2603;
128 pDRV2603 = kzalloc(sizeof(struct drv2603_data), GFP_KERNEL);
129 if (pDRV2603 == NULL) {
130 kfree(pDRV2603);
131 printk("%s,%d kzalloc fail .\n",__func__,__LINE__);
132 }
133 Haptics_init(pDRV2603);
134 dev_err(pDRV2603->to_dev.dev,"%s:enter!\n", __func__);
135 sysfs_create_group(&pDRV2603->to_dev.dev->kobj,
136 &drv2603_vibrator_attribute_group);
137 drv2603_parse_dt(pDRV2603);
138 return 0;
139}
140
141void drv2603_exit(void)
142{
143 struct drv2603_data *pDRV2603;
144 pDRV2603 = kzalloc(sizeof(struct drv2603_data), GFP_KERNEL);
145 dev_err(pDRV2603->to_dev.dev,"%s:enter!", __func__);
146 timed_output_dev_unregister(&(pDRV2603->to_dev));
147 kfree(pDRV2603);
148}
149MODULE_LICENSE("Dual BSD/GPL");
150module_init(drv2603_init);
151module_exit(drv2603_exit);
152
153
154
diff --git a/drv2603/dts.readme b/drv2603/dts.readme
new file mode 100644
index 0000000..140a48d
--- /dev/null
+++ b/drv2603/dts.readme
@@ -0,0 +1,4 @@
1tas2603 {
2 compatible = "ti_tas2603";
3 ti,reset-gpio = <&gpio1 16 0>;
4 }; \ No newline at end of file
diff --git a/drv2603/timed_output.c b/drv2603/timed_output.c
new file mode 100644
index 0000000..b8dde89
--- /dev/null
+++ b/drv2603/timed_output.c
@@ -0,0 +1,126 @@
1/* drivers/misc/timed_output.c
2 *
3 * Copyright (C) 2009 Google, Inc.
4 * Author: Mike Lockwood <lockwood@android.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#define pr_fmt(fmt) "timed_output: " fmt
18
19#include <linux/module.h>
20#include <linux/types.h>
21#include <linux/device.h>
22#include <linux/fs.h>
23#include <linux/err.h>
24
25#include "timed_output.h"
26
27static struct class *timed_output_class;
28static atomic_t device_count;
29
30static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
31 char *buf)
32{
33 struct timed_output_dev *tdev = dev_get_drvdata(dev);
34 int remaining = tdev->get_time(tdev);
35
36 return sprintf(buf, "%d\n", remaining);
37}
38
39static ssize_t enable_store(
40 struct device *dev, struct device_attribute *attr,
41 const char *buf, size_t size)
42{
43 struct timed_output_dev *tdev = dev_get_drvdata(dev);
44 int value;
45
46 if (sscanf(buf, "%d", &value) != 1)
47 return -EINVAL;
48
49 tdev->enable(tdev, value);
50
51 return size;
52}
53
54static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
55
56static int create_timed_output_class(void)
57{
58 if (!timed_output_class) {
59 timed_output_class = class_create(THIS_MODULE, "timed_output");
60 if (IS_ERR(timed_output_class))
61 return PTR_ERR(timed_output_class);
62 atomic_set(&device_count, 0);
63 }
64
65 return 0;
66}
67
68int timed_output_dev_register(struct timed_output_dev *tdev)
69{
70 int ret;
71
72 if (!tdev || !tdev->name || !tdev->enable || !tdev->get_time)
73 return -EINVAL;
74
75 ret = create_timed_output_class();
76 if (ret < 0)
77 return ret;
78
79 tdev->index = atomic_inc_return(&device_count);
80 tdev->dev = device_create(timed_output_class, NULL,
81 MKDEV(0, tdev->index), NULL, tdev->name);
82 if (IS_ERR(tdev->dev))
83 return PTR_ERR(tdev->dev);
84
85 ret = device_create_file(tdev->dev, &dev_attr_enable);
86 if (ret < 0)
87 goto err_create_file;
88
89 dev_set_drvdata(tdev->dev, tdev);
90 tdev->state = 0;
91 return 0;
92
93err_create_file:
94 device_destroy(timed_output_class, MKDEV(0, tdev->index));
95 pr_err("failed to register driver %s\n",
96 tdev->name);
97
98 return ret;
99}
100EXPORT_SYMBOL_GPL(timed_output_dev_register);
101
102void timed_output_dev_unregister(struct timed_output_dev *tdev)
103{
104 tdev->enable(tdev, 0);
105 device_remove_file(tdev->dev, &dev_attr_enable);
106 dev_set_drvdata(tdev->dev, NULL);
107 device_destroy(timed_output_class, MKDEV(0, tdev->index));
108}
109EXPORT_SYMBOL_GPL(timed_output_dev_unregister);
110
111static int __init timed_output_init(void)
112{
113 return create_timed_output_class();
114}
115
116static void __exit timed_output_exit(void)
117{
118 class_destroy(timed_output_class);
119}
120
121module_init(timed_output_init);
122module_exit(timed_output_exit);
123
124MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
125MODULE_DESCRIPTION("timed output class driver");
126MODULE_LICENSE("GPL");
diff --git a/drv2603/timed_output.h b/drv2603/timed_output.h
new file mode 100644
index 0000000..ec907ab
--- /dev/null
+++ b/drv2603/timed_output.h
@@ -0,0 +1,37 @@
1/* include/linux/timed_output.h
2 *
3 * Copyright (C) 2008 Google, Inc.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14*/
15
16#ifndef _LINUX_TIMED_OUTPUT_H
17#define _LINUX_TIMED_OUTPUT_H
18
19struct timed_output_dev {
20 const char *name;
21
22 /* enable the output and set the timer */
23 void (*enable)(struct timed_output_dev *sdev, int timeout);
24
25 /* returns the current number of milliseconds remaining on the timer */
26 int (*get_time)(struct timed_output_dev *sdev);
27
28 /* private data */
29 struct device *dev;
30 int index;
31 int state;
32};
33
34extern int timed_output_dev_register(struct timed_output_dev *dev);
35extern void timed_output_dev_unregister(struct timed_output_dev *dev);
36
37#endif