1 /* 2 * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. 3 * 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. 7 * 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. 12 */ 13 14 #include <linux/version.h> 15 #include <linux/kernel.h> 16 #include <linux/errno.h> 17 #include <linux/init.h> 18 #include <linux/tty.h> 19 #include <linux/tty_driver.h> 20 #include <linux/tty_flip.h> 21 #include <linux/module.h> 22 #include <linux/slab.h> 23 #include <linux/usb/cdc.h> 24 #include <linux/serial.h> 25 #include "gdm_tty.h" 26 27 #define GDM_TTY_MAJOR 0 28 #define GDM_TTY_MINOR 32 29 30 #define ACM_CTRL_DTR 0x01 31 #define ACM_CTRL_RTS 0x02 32 #define ACM_CTRL_DSR 0x02 33 #define ACM_CTRL_RI 0x08 34 #define ACM_CTRL_DCD 0x01 35 36 #define WRITE_SIZE 2048 37 38 #define MUX_TX_MAX_SIZE 2048 39 40 #define gdm_tty_send(n, d, l, i, c, b) (\ 41 n->tty_dev->send_func(n->tty_dev->priv_dev, d, l, i, c, b)) 42 #define gdm_tty_recv(n, c) (\ 43 n->tty_dev->recv_func(n->tty_dev->priv_dev, c)) 44 #define gdm_tty_send_control(n, r, v, d, l) (\ 45 n->tty_dev->send_control(n->tty_dev->priv_dev, r, v, d, l)) 46 47 #define acm_set_comm_feature(n, v) \ 48 gdm_tty_send_control(n, 0x02, v, NULL, 0) 49 50 #define GDM_TTY_READY(tty_str) (tty_str && tty_str->tty_dev && tty_str->port.count) 51 52 struct tty_driver *g_tty_drv[TTY_MAX_COUNT] = {NULL, }; 53 struct tty_str *g_tty_str[TTY_MAX_COUNT][GDM_TTY_MINOR] = {{NULL, }, }; 54 55 static char *DRIVER_STRING[TTY_MAX_COUNT] = {"GCTATC", "GCTDM"}; 56 static char *DEVICE_STRING[TTY_MAX_COUNT] = {"GCT-ATC", "GCT-DM"}; 57 58 static DEFINE_MUTEX(open_mutex); 59 60 static struct tty_port_operations gdm_tty_port_ops = { 61 }; 62 63 static int gdm_tty_open(struct tty_struct *tty, struct file *filp) 64 { 65 struct tty_str *tty_str = NULL; 66 int i; 67 int ret = 0; 68 69 mutex_lock(&open_mutex); 70 71 for (i = 0; i < TTY_MAX_COUNT; i++) { 72 if (!strcmp(tty->driver->driver_name, DRIVER_STRING[i])) { 73 tty_str = g_tty_str[i][tty->index]; 74 break; 75 } 76 } 77 78 if (!tty_str) { 79 printk(KERN_INFO "glte: no tty device\n"); 80 mutex_unlock(&open_mutex); 81 return -ENODEV; 82 } 83 84 set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); 85 86 tty->driver_data = tty_str; 87 tty_port_tty_set(&tty_str->port, tty); 88 tty_str->port.count++; 89 set_bit(ASYNCB_INITIALIZED, &tty_str->port.flags); 90 ret = tty_port_block_til_ready(&tty_str->port, tty, filp); 91 92 mutex_unlock(&open_mutex); 93 94 return ret; 95 } 96 97 static void gdm_tty_close(struct tty_struct *tty, struct file *filp) 98 { 99 struct tty_str *tty_str = tty->driver_data; 100 int i; 101 102 if (!tty_str) { 103 printk(KERN_INFO "glte: tty device already close\n"); 104 return; 105 } 106 107 if (tty_str->port.count != 0) { 108 tty_port_close_start(&tty_str->port, tty, filp); 109 tty_port_close_end(&tty_str->port, tty); 110 111 if (tty_str->port.count == 0) 112 tty_port_tty_set(&tty_str->port, NULL); 113 tty_str->port.tty = NULL; 114 } 115 116 if (!tty_str->tty_dev) { 117 for (i = 0; i < TTY_MAX_COUNT; i++) { 118 if (!strcmp(tty->driver->driver_name, DRIVER_STRING[i])) 119 break; 120 } 121 122 if (i < TTY_MAX_COUNT) { 123 tty_unregister_device(g_tty_drv[i], tty->index); 124 tty_port_tty_set(&tty_str->port, NULL); 125 kfree(tty_str); 126 g_tty_str[i][tty->index] = NULL; 127 } 128 } 129 } 130 131 static int gdm_tty_recv_complete(void *data, int len, int index, int minor, int complete) 132 { 133 struct tty_str *tty_str = g_tty_str[index][minor]; 134 struct tty_port *tty_port; 135 136 if (!GDM_TTY_READY(tty_str)) { 137 if (complete == RECV_PACKET_PROCESS_COMPLETE) 138 gdm_tty_recv(tty_str, gdm_tty_recv_complete); 139 return TO_HOST_PORT_CLOSE; 140 } 141 142 if (!data || !len) 143 goto complete_routine; 144 145 tty_port = &tty_str->port; 146 147 if (tty_buffer_request_room(tty_port, len) == len) { 148 tty_insert_flip_string(tty_port, data, len); 149 tty_flip_buffer_push(tty_port); 150 } else { 151 return TO_HOST_BUFFER_REQUEST_FAIL; 152 } 153 154 complete_routine: 155 if (complete == RECV_PACKET_PROCESS_COMPLETE) 156 gdm_tty_recv(tty_str, gdm_tty_recv_complete); 157 158 return TO_HOST_SUCCESS; 159 } 160 161 static void gdm_tty_send_complete(void *arg) 162 { 163 struct tty_str *tty_str = (struct tty_str *)arg; 164 struct tty_struct *tty; 165 166 if (!GDM_TTY_READY(tty_str)) 167 return; 168 169 tty = tty_port_tty_get(&tty_str->port); 170 tty_wakeup(tty); 171 tty_kref_put(tty); 172 } 173 174 static int gdm_tty_write(struct tty_struct *tty, const unsigned char *buf, int len) 175 { 176 struct tty_str *tty_str = tty->driver_data; 177 int remain = len; 178 int sent_len = 0; 179 int sending_len = 0; 180 181 if (!GDM_TTY_READY(tty_str)) 182 return -ENODEV; 183 184 if (!len) 185 return 0; 186 187 while (1) { 188 sending_len = remain > MUX_TX_MAX_SIZE ? MUX_TX_MAX_SIZE : remain; 189 gdm_tty_send(tty_str, 190 (void *)(buf+sent_len), 191 sending_len, 192 tty_str->tty_drv_index, 193 gdm_tty_send_complete, 194 tty_str 195 ); 196 sent_len += sending_len; 197 remain -= sending_len; 198 if (remain <= 0) 199 break; 200 } 201 202 return len; 203 } 204 205 static int gdm_tty_write_room(struct tty_struct *tty) 206 { 207 struct tty_str *tty_str = tty->driver_data; 208 209 if (!GDM_TTY_READY(tty_str)) 210 return -ENODEV; 211 212 return WRITE_SIZE; 213 } 214 215 static int gdm_tty_tiocmget(struct tty_struct *tty) 216 { 217 struct tty_str *tty_str = tty->driver_data; 218 219 if (!GDM_TTY_READY(tty_str)) 220 return -ENODEV; 221 222 return (0 & ACM_CTRL_DTR ? TIOCM_DTR : 0) | 223 (0 & ACM_CTRL_RTS ? TIOCM_RTS : 0) | 224 (0 & ACM_CTRL_DSR ? TIOCM_DSR : 0) | 225 (0 & ACM_CTRL_RI ? TIOCM_RI : 0) | 226 (0 & ACM_CTRL_DCD ? TIOCM_CD : 0) | 227 TIOCM_CTS; 228 } 229 230 static int gdm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) 231 { 232 struct tty_str *tty_str = tty->driver_data; 233 234 if (!GDM_TTY_READY(tty_str)) 235 return -ENODEV; 236 237 return 1; 238 } 239 240 int register_lte_tty_device(struct tty_dev *tty_dev, struct device *dev) 241 { 242 struct tty_str *tty_str; 243 int i, j; 244 245 for (i = 0; i < TTY_MAX_COUNT; i++) { 246 for (j = 0; j < GDM_TTY_MINOR; j++) { 247 if (!g_tty_str[i][j]) 248 break; 249 } 250 251 if (j == GDM_TTY_MINOR) { 252 tty_dev->minor[i] = j; 253 return -1; 254 } 255 256 tty_str = kmalloc(sizeof(struct tty_str), GFP_KERNEL); 257 if (!tty_str) 258 return -ENOMEM; 259 260 g_tty_str[i][j] = tty_str; 261 262 tty_str->tty_dev = tty_dev; 263 tty_str->tty_drv_index = i; 264 tty_dev->minor[i] = j; 265 tty_port_init(&tty_str->port); 266 tty_str->port.ops = &gdm_tty_port_ops; 267 268 if (strcmp(DEVICE_STRING[i], "GCT-ATC") != 0) 269 dev = NULL; 270 tty_register_device(g_tty_drv[i], j, dev); 271 } 272 273 acm_set_comm_feature(tty_str, 1); 274 275 for (i = 0; i < MAX_ISSUE_NUM; i++) 276 gdm_tty_recv(tty_str, gdm_tty_recv_complete); 277 278 return 0; 279 } 280 281 void unregister_lte_tty_device(struct tty_dev *tty_dev) 282 { 283 struct tty_str *tty_str; 284 int i; 285 286 for (i = 0; i < TTY_MAX_COUNT; i++) { 287 if (tty_dev->minor[i] >= GDM_TTY_MINOR) 288 continue; 289 290 tty_str = g_tty_str[i][tty_dev->minor[i]]; 291 if (!tty_str) 292 continue; 293 294 tty_str->tty_dev = NULL; 295 296 if (!tty_str->port.count) { 297 tty_unregister_device(g_tty_drv[i], tty_dev->minor[i]); 298 tty_port_tty_set(&tty_str->port, NULL); 299 kfree(tty_str); 300 g_tty_str[i][tty_dev->minor[i]] = NULL; 301 } 302 } 303 } 304 305 static void gdm_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old) 306 { 307 return; 308 } 309 310 static const struct tty_operations gdm_tty_ops = { 311 .open = gdm_tty_open, 312 .close = gdm_tty_close, 313 .write = gdm_tty_write, 314 .write_room = gdm_tty_write_room, 315 .tiocmget = gdm_tty_tiocmget, 316 .tiocmset = gdm_tty_tiocmset, 317 .set_termios = gdm_tty_set_termios, 318 }; 319 320 int register_lte_tty_driver(void) 321 { 322 struct tty_driver *tty_driver = NULL; 323 int i; 324 int ret; 325 326 for (i = 0; i < TTY_MAX_COUNT; i++) { 327 tty_driver = alloc_tty_driver(GDM_TTY_MINOR); 328 if (!tty_driver) { 329 printk(KERN_ERR "glte: alloc_tty_driver fail\n"); 330 return -ENOMEM; 331 } 332 333 tty_driver->owner = THIS_MODULE; 334 tty_driver->driver_name = DRIVER_STRING[i]; 335 tty_driver->name = DEVICE_STRING[i]; 336 tty_driver->major = GDM_TTY_MAJOR; 337 tty_driver->type = TTY_DRIVER_TYPE_SERIAL; 338 tty_driver->subtype = SERIAL_TYPE_NORMAL; 339 tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; 340 tty_driver->init_termios = tty_std_termios; 341 tty_driver->init_termios.c_cflag = B9600 | CS8 | HUPCL | CLOCAL; 342 tty_driver->init_termios.c_lflag = ISIG | ICANON | IEXTEN; 343 tty_set_operations(tty_driver, &gdm_tty_ops); 344 345 ret = tty_register_driver(tty_driver); 346 347 g_tty_drv[i] = tty_driver; 348 } 349 350 return ret; 351 } 352 353 void unregister_lte_tty_driver(void) 354 { 355 struct tty_driver *tty_driver; 356 int i; 357 358 for (i = 0; i < TTY_MAX_COUNT; i++) { 359 tty_driver = g_tty_drv[i]; 360 if (tty_driver) { 361 tty_unregister_driver(tty_driver); 362 put_tty_driver(tty_driver); 363 } 364 } 365 } 366