import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / video / mt8127 / mtkfb_vsync.c
1 #include <linux/kernel.h>
2 #include <linux/mm.h>
3 #include <linux/mm_types.h>
4 #include <linux/module.h>
5 #include <generated/autoconf.h>
6 #include <linux/init.h>
7 #include <linux/types.h>
8 #include <linux/cdev.h>
9 #include <linux/kdev_t.h>
10 #include <linux/delay.h>
11 #include <linux/ioport.h>
12 #include <linux/platform_device.h>
13 #include <linux/dma-mapping.h>
14 #include <linux/device.h>
15 #include <linux/fs.h>
16 #include <linux/interrupt.h>
17 #include <linux/wait.h>
18 #include <linux/spinlock.h>
19 #include <linux/param.h>
20 #include <linux/uaccess.h>
21 #include <linux/sched.h>
22
23 #include <linux/workqueue.h>
24 #include <linux/semaphore.h>
25 #include <linux/slab.h>
26
27 #include "mtkfb_vsync.h"
28
29 #include <linux/xlog.h>
30
31 #define VSYNC_DBG(...) xlog_printk(ANDROID_LOG_DEBUG, MTKFB_VSYNC_DEVNAME, __VA_ARGS__)
32
33 #define VSYNC_INF(...) xlog_printk(ANDROID_LOG_INFO, MTKFB_VSYNC_DEVNAME, __VA_ARGS__)
34 #define VSYNC_WRN(...) xlog_printk(ANDROID_LOG_WARN, MTKFB_VSYNC_DEVNAME, __VA_ARGS__)
35 #define VSYNC_ERR(...) xlog_printk(ANDROID_LOG_ERROR, MTKFB_VSYNC_DEVNAME, __VA_ARGS__)
36
37 static size_t mtkfb_vsync_on = false;
38 #define MTKFB_VSYNC_LOG(fmt, arg...) \
39 do { \
40 if (mtkfb_vsync_on) VSYNC_WRN(fmt, ##arg); \
41 }while (0)
42
43 #define MTKFB_VSYNC_FUNC() \
44 do { \
45 if(mtkfb_vsync_on) VSYNC_WRN("[Func]%s\n", __func__); \
46 }while (0)
47
48 static dev_t mtkfb_vsync_devno;
49 static struct cdev *mtkfb_vsync_cdev;
50 static struct class *mtkfb_vsync_class = NULL;
51
52 DEFINE_SEMAPHORE(mtkfb_vsync_sem);
53
54 extern void mtkfb_waitVsync(void);
55 extern void mtkfb_disable_non_fb_layer(void);
56
57 void mtkfb_vsync_log_enable(int enable)
58 {
59 mtkfb_vsync_on = enable;
60 MTKFB_VSYNC_LOG("mtkfb_vsync log %s\n", enable?"enabled":"disabled");
61 }
62
63 static int mtkfb_vsync_open(struct inode *inode, struct file *file)
64 {
65 VSYNC_DBG("driver open\n");
66 return 0;
67 }
68
69 static ssize_t mtkfb_vsync_read(struct file *file, char __user *data, size_t len, loff_t *ppos)
70 {
71 VSYNC_DBG("driver read\n");
72 return 0;
73 }
74
75 static int mtkfb_vsync_release(struct inode *inode, struct file *file)
76 {
77 VSYNC_DBG("driver release\n");
78 VSYNC_DBG("reset overlay engine\n");
79 //mtkfb_disable_non_fb_layer(); //[mo]
80 return 0;
81 }
82
83 static int mtkfb_vsync_flush(struct file * a_pstFile , fl_owner_t a_id)
84 {
85 // To Do : error handling here
86 return 0;
87 }
88
89 static long mtkfb_vsync_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
90 {
91 int ret = 0;
92 MTKFB_VSYNC_FUNC();
93 switch (cmd)
94 {
95 case MTKFB_VSYNC_IOCTL:
96 {
97 MTKFB_VSYNC_LOG("[MTKFB_VSYNC]: enter MTKFB_VSYNC_IOCTL\n");
98 if (down_interruptible(&mtkfb_vsync_sem)) {
99 pr_info("[mtkfb_vsync_ioctl] can't get semaphore,%d\n", __LINE__);
100 msleep(20);
101 return ret;
102 }
103 mtkfb_waitVsync();
104 up(&mtkfb_vsync_sem);
105 MTKFB_VSYNC_LOG("[MTKFB_VSYNC]: leave MTKFB_VSYNC_IOCTL\n");
106 }
107 break;
108 }
109 return ret;
110 }
111
112
113 static struct file_operations mtkfb_vsync_fops = {
114 .owner = THIS_MODULE,
115 .unlocked_ioctl = mtkfb_vsync_unlocked_ioctl,
116 .open = mtkfb_vsync_open,
117 .release = mtkfb_vsync_release,
118 .flush = mtkfb_vsync_flush,
119 .read = mtkfb_vsync_read,
120 };
121
122 static int mtkfb_vsync_probe(struct platform_device *pdev)
123 {
124 struct class_device;
125 struct class_device *class_dev = NULL;
126
127 pr_info("\n=== MTKFB_VSYNC probe ===\n");
128
129 if (alloc_chrdev_region(&mtkfb_vsync_devno, 0, 1, MTKFB_VSYNC_DEVNAME))
130 {
131 VSYNC_ERR("can't get device major number...\n");
132 return -EFAULT;
133 }
134
135 pr_info("get device major number (%d)\n", mtkfb_vsync_devno);
136
137 mtkfb_vsync_cdev = cdev_alloc();
138 mtkfb_vsync_cdev->owner = THIS_MODULE;
139 mtkfb_vsync_cdev->ops = &mtkfb_vsync_fops;
140
141 cdev_add(mtkfb_vsync_cdev, mtkfb_vsync_devno, 1);
142
143 mtkfb_vsync_class = class_create(THIS_MODULE, MTKFB_VSYNC_DEVNAME);
144 class_dev = (struct class_device *)device_create(mtkfb_vsync_class, NULL, mtkfb_vsync_devno, NULL, MTKFB_VSYNC_DEVNAME);
145
146 VSYNC_INF("probe is done\n");
147 return 0;
148 }
149
150 static int mtkfb_vsync_remove(struct platform_device *pdev)
151 {
152 VSYNC_INF("device remove\n");
153 return 0;
154 }
155
156 static void mtkfb_vsync_shutdown(struct platform_device *pdev)
157 {
158 pr_info("mtkfb_vsync device shutdown\n");
159 }
160
161 static int mtkfb_vsync_suspend(struct platform_device *pdev, pm_message_t mesg)
162 {
163 return 0;
164 }
165
166 static int mtkfb_vsync_resume(struct platform_device *pdev)
167 {
168 return 0;
169 }
170
171 static struct platform_driver mtkfb_vsync_driver = {
172 .probe = mtkfb_vsync_probe,
173 .remove = mtkfb_vsync_remove,
174 .shutdown = mtkfb_vsync_shutdown,
175 .suspend = mtkfb_vsync_suspend,
176 .resume = mtkfb_vsync_resume,
177 .driver = {
178 .name = MTKFB_VSYNC_DEVNAME,
179 },
180 };
181
182 static void mtkfb_vsync_device_release(struct device *dev)
183 {
184 }
185
186 static u64 mtkfb_vsync_dmamask = ~(u32)0;
187
188 static struct platform_device mtkfb_vsync_device = {
189 .name = MTKFB_VSYNC_DEVNAME,
190 .id = 0,
191 .dev = {
192 .release = mtkfb_vsync_device_release,
193 .dma_mask = &mtkfb_vsync_dmamask,
194 .coherent_dma_mask = 0xffffffff,
195 },
196 .num_resources = 0,
197 };
198
199 static int __init mtkfb_vsync_init(void)
200 {
201 VSYNC_INF("initializeing driver...\n");
202
203 if (platform_device_register(&mtkfb_vsync_device))
204 {
205 VSYNC_ERR("failed to register device\n");
206 return -ENODEV;
207 }
208
209 if (platform_driver_register(&mtkfb_vsync_driver))
210 {
211 VSYNC_ERR("failed to register driver\n");
212 platform_device_unregister(&mtkfb_vsync_device);
213 return -ENODEV;
214 }
215
216 return 0;
217 }
218
219 static void __exit mtkfb_vsync_exit(void)
220 {
221 cdev_del(mtkfb_vsync_cdev);
222 unregister_chrdev_region(mtkfb_vsync_devno, 1);
223
224 platform_driver_unregister(&mtkfb_vsync_driver);
225 platform_device_unregister(&mtkfb_vsync_device);
226
227 device_destroy(mtkfb_vsync_class, mtkfb_vsync_devno);
228 class_destroy(mtkfb_vsync_class);
229
230 VSYNC_INF("exit driver...\n");
231 }
232
233 module_init(mtkfb_vsync_init);
234 module_exit(mtkfb_vsync_exit);
235
236 MODULE_DESCRIPTION("MediaTek FB VSYNC Driver");
237 MODULE_AUTHOR("Zaikuo Wang <Zaikuo.Wang@mediatek.com>");