2 * Copyright (C) 2012 Spreadtrum Communications Inc.
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <linux/slab.h>
19 #include <linux/sipc.h>
20 #include <linux/stty.h>
21 #include <linux/types.h>
22 #include <linux/kdev_t.h>
23 #include <linux/tty.h>
24 #include <linux/vt_kern.h>
25 #include <linux/init.h>
26 #include <linux/console.h>
27 #include <linux/delay.h>
29 #include <linux/of_device.h>
32 #include <linux/compat.h>
33 #include <linux/tty_flip.h>
34 #include <linux/kthread.h>
36 #ifdef CONFIG_SPRD_2351
37 #include <linux/sprd_2351.h>
41 #define STTY_DEV_MAX_NR 1
42 #define STTY_MAX_DATA_LEN 4096
44 #define STTY_STATE_OPEN 1
45 #define STTY_STATE_CLOSE 0
48 struct stty_init_data *pdata;
49 struct tty_port *port;
50 struct tty_struct *tty;
51 struct tty_driver *driver;
55 struct mutex stat_lock;
58 static void stty_handler (int event, void* data)
60 struct stty_device *stty = data;
62 unsigned char buf[STTY_MAX_DATA_LEN] = {0};
64 pr_debug("stty handler event=%d \n", event);
67 case SBUF_NOTIFY_WRITE:
69 case SBUF_NOTIFY_READ:
70 cnt = sbuf_read(stty->pdata->dst, stty->pdata->channel,
71 stty->pdata->bufid,(void *)buf, STTY_MAX_DATA_LEN, 0);
72 pr_debug("stty handler read data len =%d \n", cnt);
73 mutex_lock(&(stty->stat_lock));
74 if ((stty->state == STTY_STATE_OPEN) && (cnt > 0)) {
75 for(i = 0; i < cnt; i++) {
76 tty_insert_flip_char(stty->port, buf[i], TTY_NORMAL);
78 tty_schedule_flip(stty->port);
80 mutex_unlock(&(stty->stat_lock));
83 printk(KERN_ERR "Received event is invalid(event=%d)\n", event);
89 static int stty_open(struct tty_struct *tty, struct file * filp)
91 struct stty_device *stty = NULL;
92 struct tty_driver *driver = NULL;
95 printk(KERN_ERR "stty open input tty is NULL!\n");
99 stty = (struct stty_device *)driver->driver_state;
102 printk(KERN_ERR "stty open input stty NULL!\n");
106 if (sbuf_status(stty->pdata->dst, stty->pdata->channel) != 0) {
107 printk(KERN_ERR "stty_open sbuf not ready to open!dst=%d,channel=%d\n"
108 ,stty->pdata->dst,stty->pdata->channel);
112 tty->driver_data = (void *)stty;
114 mutex_lock(&(stty->stat_lock));
115 stty->state = STTY_STATE_OPEN;
116 mutex_unlock(&(stty->stat_lock));
118 #ifdef CONFIG_SPRD_2351
119 rf2351_gpio_ctrl_power_enable(1);
121 #ifdef CONFIG_ARCH_SCX20
122 rf2351_vddwpa_ctrl_power_enable(1);
125 pr_debug("stty_open device success! \n");
130 static void stty_close(struct tty_struct *tty, struct file * filp)
132 struct stty_device *stty = NULL;
135 printk(KERN_ERR "stty close input tty is NULL!\n");
138 stty = (struct stty_device *) tty->driver_data;
140 printk(KERN_ERR "stty close s tty is NULL!\n");
144 mutex_lock(&(stty->stat_lock));
145 stty->state = STTY_STATE_CLOSE;
146 mutex_unlock(&(stty->stat_lock));
148 pr_debug("stty_close device success !\n");
150 #ifdef CONFIG_SPRD_2351
151 rf2351_gpio_ctrl_power_enable(0);
153 #ifdef CONFIG_ARCH_SCX20
154 rf2351_vddwpa_ctrl_power_enable(0);
160 static int stty_write(struct tty_struct * tty,
161 const unsigned char *buf, int count)
163 struct stty_device *stty = tty->driver_data;
165 pr_debug("stty write count=%d \n", count);
167 cnt = sbuf_write(stty->pdata->dst, stty->pdata->channel,
168 stty->pdata->bufid, (void *)buf, count, -1);
173 static void stty_flush_chars(struct tty_struct *tty)
178 static int stty_write_room(struct tty_struct *tty)
183 static const struct tty_operations stty_ops = {
187 .flush_chars = stty_flush_chars,
188 .write_room = stty_write_room,
191 static struct tty_port *stty_port_init()
193 struct tty_port *port = NULL;
195 port = kzalloc(sizeof(struct tty_port),GFP_KERNEL);
197 printk(KERN_ERR "stty_port_init Failed to allocate device!\n");
204 static int stty_driver_init(struct stty_device *device)
206 struct tty_driver *driver;
209 mutex_init(&(device->stat_lock));
211 device->port = stty_port_init();
216 driver = alloc_tty_driver(STTY_DEV_MAX_NR);
220 * Initialize the tty_driver structure
221 * Entries in stty_driver that are NOT initialized:
222 * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc
224 driver->owner = THIS_MODULE;
225 driver->driver_name = device->pdata->name;
226 driver->name = device->pdata->name;
228 driver->type = TTY_DRIVER_TYPE_SYSTEM;
229 driver->subtype = SYSTEM_TYPE_TTY;
230 driver->init_termios = tty_std_termios;
231 driver->driver_state = (void*)device;
232 device->driver = driver;
233 /* initialize the tty driver */
234 tty_set_operations(driver, &stty_ops);
235 tty_port_link_device(device->port, driver, 0);
236 ret = tty_register_driver(driver);
238 put_tty_driver(driver);
239 tty_port_destroy(device->port);
245 static void stty_driver_exit(struct stty_device *device)
247 struct tty_driver *driver = device->driver;
248 tty_unregister_driver(driver);
249 tty_port_destroy(device->port);
252 static int stty_parse_dt(struct stty_init_data **init, struct device *dev)
255 struct of_device_node *np = dev->of_node;
256 struct stty_init_data *pdata = NULL;
260 pdata = kzalloc(sizeof(struct stty_init_data), GFP_KERNEL);
265 ret = of_property_read_string(np, "sprd,name", (const char **)&pdata->name);
270 ret = of_property_read_u32(np, "sprd,dst", (uint32_t *)&data);
274 pdata->dst = (uint8_t)data;
276 ret = of_property_read_u32(np, "sprd,channel", (uint32_t *)&data);
280 pdata->channel = (uint8_t)data;
282 ret = of_property_read_u32(np, "sprd,bufid", (uint32_t *)&pdata->bufid);
298 static inline void stty_destroy_pdata(struct stty_init_data **init)
301 struct stty_init_data *pdata = *init;
314 static int stty_probe(struct platform_device *pdev)
316 struct stty_init_data *pdata = (struct stty_init_data*)pdev->dev.platform_data;
317 struct stty_device *stty;
320 if (pdev->dev.of_node && !pdata) {
321 rval = stty_parse_dt(&pdata, &pdev->dev);
323 printk(KERN_ERR "failed to parse styy device tree, ret=%d\n", rval);
327 pr_info("stty: after parse device tree, name=%s, dst=%u, channel=%u, bufid=%u\n",
328 pdata->name, pdata->dst, pdata->channel, pdata->bufid);
330 stty = kzalloc(sizeof(struct stty_device),GFP_KERNEL);
332 stty_destroy_pdata(&pdata);
333 printk(KERN_ERR "stty Failed to allocate device!\n");
338 rval = stty_driver_init(stty);
341 stty_destroy_pdata(&pdata);
342 printk(KERN_ERR "stty driver init error!\n");
346 rval = sbuf_register_notifier(pdata->dst, pdata->channel,
347 pdata->bufid, stty_handler, stty);
349 stty_driver_exit(stty);
352 printk(KERN_ERR "regitster notifier failed (%d)\n", rval);
356 printk( "stty_probe init device addr: 0x%0x\n", (void *)stty);
357 platform_set_drvdata(pdev, stty);
362 static int stty_remove(struct platform_device *pdev)
364 struct stty_device *stty = platform_get_drvdata(pdev);
367 rval = sbuf_register_notifier(stty->pdata->dst, stty->pdata->channel,
368 stty->pdata->bufid, NULL, NULL);
370 printk(KERN_ERR " unregitster notifier failed (%d)\n", rval);
374 stty_driver_exit(stty);
376 stty_destroy_pdata(&stty->pdata);
378 platform_set_drvdata(pdev, NULL);
382 static const struct of_device_id stty_match_table[] = {
383 { .compatible = "sprd,stty4bt", },
387 static struct platform_driver stty_driver = {
389 .owner = THIS_MODULE,
391 .of_match_table = stty_match_table,
394 .remove = stty_remove,
397 static int __init stty_init(void)
399 return platform_driver_register(&stty_driver);
402 static void __exit stty_exit(void)
404 platform_driver_unregister(&stty_driver);
407 late_initcall(stty_init);
408 module_exit(stty_exit);
410 MODULE_AUTHOR("Dewu Jiang");
411 MODULE_DESCRIPTION("SIPC/stty driver");
412 MODULE_LICENSE("GPL");