1cd6484e1SRob Herring /* 2cd6484e1SRob Herring * Copyright (C) 2016-2017 Linaro Ltd., Rob Herring <[email protected]> 3cd6484e1SRob Herring * 4cd6484e1SRob Herring * This program is free software; you can redistribute it and/or modify 5cd6484e1SRob Herring * it under the terms of the GNU General Public License version 2 and 6cd6484e1SRob Herring * only version 2 as published by the Free Software Foundation. 7cd6484e1SRob Herring * 8cd6484e1SRob Herring * This program is distributed in the hope that it will be useful, 9cd6484e1SRob Herring * but WITHOUT ANY WARRANTY; without even the implied warranty of 10cd6484e1SRob Herring * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11cd6484e1SRob Herring * GNU General Public License for more details. 12cd6484e1SRob Herring */ 13cd6484e1SRob Herring #ifndef _LINUX_SERDEV_H 14cd6484e1SRob Herring #define _LINUX_SERDEV_H 15cd6484e1SRob Herring 16cd6484e1SRob Herring #include <linux/types.h> 17cd6484e1SRob Herring #include <linux/device.h> 185659dab2SSebastian Reichel #include <linux/termios.h> 19756db778SSebastian Reichel #include <linux/delay.h> 20cd6484e1SRob Herring 21cd6484e1SRob Herring struct serdev_controller; 22cd6484e1SRob Herring struct serdev_device; 23cd6484e1SRob Herring 24cd6484e1SRob Herring /* 25cd6484e1SRob Herring * serdev device structures 26cd6484e1SRob Herring */ 27cd6484e1SRob Herring 28cd6484e1SRob Herring /** 29cd6484e1SRob Herring * struct serdev_device_ops - Callback operations for a serdev device 30cd6484e1SRob Herring * @receive_buf: Function called with data received from device. 31cd6484e1SRob Herring * @write_wakeup: Function called when ready to transmit more data. 32cd6484e1SRob Herring */ 33cd6484e1SRob Herring struct serdev_device_ops { 34cd6484e1SRob Herring int (*receive_buf)(struct serdev_device *, const unsigned char *, size_t); 35cd6484e1SRob Herring void (*write_wakeup)(struct serdev_device *); 36cd6484e1SRob Herring }; 37cd6484e1SRob Herring 38cd6484e1SRob Herring /** 39cd6484e1SRob Herring * struct serdev_device - Basic representation of an serdev device 40cd6484e1SRob Herring * @dev: Driver model representation of the device. 41cd6484e1SRob Herring * @nr: Device number on serdev bus. 42cd6484e1SRob Herring * @ctrl: serdev controller managing this device. 43cd6484e1SRob Herring * @ops: Device operations. 446fe729c4SAndrey Smirnov * @write_comp Completion used by serdev_device_write() internally 456fe729c4SAndrey Smirnov * @write_lock Lock to serialize access when writing data 46cd6484e1SRob Herring */ 47cd6484e1SRob Herring struct serdev_device { 48cd6484e1SRob Herring struct device dev; 49cd6484e1SRob Herring int nr; 50cd6484e1SRob Herring struct serdev_controller *ctrl; 51cd6484e1SRob Herring const struct serdev_device_ops *ops; 526fe729c4SAndrey Smirnov struct completion write_comp; 536fe729c4SAndrey Smirnov struct mutex write_lock; 54cd6484e1SRob Herring }; 55cd6484e1SRob Herring 56cd6484e1SRob Herring static inline struct serdev_device *to_serdev_device(struct device *d) 57cd6484e1SRob Herring { 58cd6484e1SRob Herring return container_of(d, struct serdev_device, dev); 59cd6484e1SRob Herring } 60cd6484e1SRob Herring 61cd6484e1SRob Herring /** 62cd6484e1SRob Herring * struct serdev_device_driver - serdev slave device driver 63cd6484e1SRob Herring * @driver: serdev device drivers should initialize name field of this 64cd6484e1SRob Herring * structure. 65cd6484e1SRob Herring * @probe: binds this driver to a serdev device. 66cd6484e1SRob Herring * @remove: unbinds this driver from the serdev device. 67cd6484e1SRob Herring */ 68cd6484e1SRob Herring struct serdev_device_driver { 69cd6484e1SRob Herring struct device_driver driver; 70cd6484e1SRob Herring int (*probe)(struct serdev_device *); 71cd6484e1SRob Herring void (*remove)(struct serdev_device *); 72cd6484e1SRob Herring }; 73cd6484e1SRob Herring 74cd6484e1SRob Herring static inline struct serdev_device_driver *to_serdev_device_driver(struct device_driver *d) 75cd6484e1SRob Herring { 76cd6484e1SRob Herring return container_of(d, struct serdev_device_driver, driver); 77cd6484e1SRob Herring } 78cd6484e1SRob Herring 79cd6484e1SRob Herring /* 80cd6484e1SRob Herring * serdev controller structures 81cd6484e1SRob Herring */ 82cd6484e1SRob Herring struct serdev_controller_ops { 83cd6484e1SRob Herring int (*write_buf)(struct serdev_controller *, const unsigned char *, size_t); 84cd6484e1SRob Herring void (*write_flush)(struct serdev_controller *); 85cd6484e1SRob Herring int (*write_room)(struct serdev_controller *); 86cd6484e1SRob Herring int (*open)(struct serdev_controller *); 87cd6484e1SRob Herring void (*close)(struct serdev_controller *); 88cd6484e1SRob Herring void (*set_flow_control)(struct serdev_controller *, bool); 89cd6484e1SRob Herring unsigned int (*set_baudrate)(struct serdev_controller *, unsigned int); 90b3f80c8fSSebastian Reichel void (*wait_until_sent)(struct serdev_controller *, long); 915659dab2SSebastian Reichel int (*get_tiocm)(struct serdev_controller *); 925659dab2SSebastian Reichel int (*set_tiocm)(struct serdev_controller *, unsigned int, unsigned int); 93cd6484e1SRob Herring }; 94cd6484e1SRob Herring 95cd6484e1SRob Herring /** 96cd6484e1SRob Herring * struct serdev_controller - interface to the serdev controller 97cd6484e1SRob Herring * @dev: Driver model representation of the device. 98cd6484e1SRob Herring * @nr: number identifier for this controller/bus. 99cd6484e1SRob Herring * @serdev: Pointer to slave device for this controller. 100cd6484e1SRob Herring * @ops: Controller operations. 101cd6484e1SRob Herring */ 102cd6484e1SRob Herring struct serdev_controller { 103cd6484e1SRob Herring struct device dev; 104cd6484e1SRob Herring unsigned int nr; 105cd6484e1SRob Herring struct serdev_device *serdev; 106cd6484e1SRob Herring const struct serdev_controller_ops *ops; 107cd6484e1SRob Herring }; 108cd6484e1SRob Herring 109cd6484e1SRob Herring static inline struct serdev_controller *to_serdev_controller(struct device *d) 110cd6484e1SRob Herring { 111cd6484e1SRob Herring return container_of(d, struct serdev_controller, dev); 112cd6484e1SRob Herring } 113cd6484e1SRob Herring 114cd6484e1SRob Herring static inline void *serdev_device_get_drvdata(const struct serdev_device *serdev) 115cd6484e1SRob Herring { 116cd6484e1SRob Herring return dev_get_drvdata(&serdev->dev); 117cd6484e1SRob Herring } 118cd6484e1SRob Herring 119cd6484e1SRob Herring static inline void serdev_device_set_drvdata(struct serdev_device *serdev, void *data) 120cd6484e1SRob Herring { 121cd6484e1SRob Herring dev_set_drvdata(&serdev->dev, data); 122cd6484e1SRob Herring } 123cd6484e1SRob Herring 124cd6484e1SRob Herring /** 125cd6484e1SRob Herring * serdev_device_put() - decrement serdev device refcount 126cd6484e1SRob Herring * @serdev serdev device. 127cd6484e1SRob Herring */ 128cd6484e1SRob Herring static inline void serdev_device_put(struct serdev_device *serdev) 129cd6484e1SRob Herring { 130cd6484e1SRob Herring if (serdev) 131cd6484e1SRob Herring put_device(&serdev->dev); 132cd6484e1SRob Herring } 133cd6484e1SRob Herring 134cd6484e1SRob Herring static inline void serdev_device_set_client_ops(struct serdev_device *serdev, 135cd6484e1SRob Herring const struct serdev_device_ops *ops) 136cd6484e1SRob Herring { 137cd6484e1SRob Herring serdev->ops = ops; 138cd6484e1SRob Herring } 139cd6484e1SRob Herring 140cd6484e1SRob Herring static inline 141cd6484e1SRob Herring void *serdev_controller_get_drvdata(const struct serdev_controller *ctrl) 142cd6484e1SRob Herring { 143cd6484e1SRob Herring return ctrl ? dev_get_drvdata(&ctrl->dev) : NULL; 144cd6484e1SRob Herring } 145cd6484e1SRob Herring 146cd6484e1SRob Herring static inline void serdev_controller_set_drvdata(struct serdev_controller *ctrl, 147cd6484e1SRob Herring void *data) 148cd6484e1SRob Herring { 149cd6484e1SRob Herring dev_set_drvdata(&ctrl->dev, data); 150cd6484e1SRob Herring } 151cd6484e1SRob Herring 152cd6484e1SRob Herring /** 153cd6484e1SRob Herring * serdev_controller_put() - decrement controller refcount 154cd6484e1SRob Herring * @ctrl serdev controller. 155cd6484e1SRob Herring */ 156cd6484e1SRob Herring static inline void serdev_controller_put(struct serdev_controller *ctrl) 157cd6484e1SRob Herring { 158cd6484e1SRob Herring if (ctrl) 159cd6484e1SRob Herring put_device(&ctrl->dev); 160cd6484e1SRob Herring } 161cd6484e1SRob Herring 162cd6484e1SRob Herring struct serdev_device *serdev_device_alloc(struct serdev_controller *); 163cd6484e1SRob Herring int serdev_device_add(struct serdev_device *); 164cd6484e1SRob Herring void serdev_device_remove(struct serdev_device *); 165cd6484e1SRob Herring 166cd6484e1SRob Herring struct serdev_controller *serdev_controller_alloc(struct device *, size_t); 167cd6484e1SRob Herring int serdev_controller_add(struct serdev_controller *); 168cd6484e1SRob Herring void serdev_controller_remove(struct serdev_controller *); 169cd6484e1SRob Herring 170cd6484e1SRob Herring static inline void serdev_controller_write_wakeup(struct serdev_controller *ctrl) 171cd6484e1SRob Herring { 172cd6484e1SRob Herring struct serdev_device *serdev = ctrl->serdev; 173cd6484e1SRob Herring 174cd6484e1SRob Herring if (!serdev || !serdev->ops->write_wakeup) 175cd6484e1SRob Herring return; 176cd6484e1SRob Herring 1779d1d994dSAndrey Smirnov serdev->ops->write_wakeup(serdev); 178cd6484e1SRob Herring } 179cd6484e1SRob Herring 180cd6484e1SRob Herring static inline int serdev_controller_receive_buf(struct serdev_controller *ctrl, 181cd6484e1SRob Herring const unsigned char *data, 182cd6484e1SRob Herring size_t count) 183cd6484e1SRob Herring { 184cd6484e1SRob Herring struct serdev_device *serdev = ctrl->serdev; 185cd6484e1SRob Herring 186cd6484e1SRob Herring if (!serdev || !serdev->ops->receive_buf) 187cd6484e1SRob Herring return -EINVAL; 188cd6484e1SRob Herring 1899d1d994dSAndrey Smirnov return serdev->ops->receive_buf(serdev, data, count); 190cd6484e1SRob Herring } 191cd6484e1SRob Herring 192cd6484e1SRob Herring #if IS_ENABLED(CONFIG_SERIAL_DEV_BUS) 193cd6484e1SRob Herring 194cd6484e1SRob Herring int serdev_device_open(struct serdev_device *); 195cd6484e1SRob Herring void serdev_device_close(struct serdev_device *); 196*2cb67d20SAndrey Smirnov int devm_serdev_device_open(struct device *, struct serdev_device *); 197cd6484e1SRob Herring unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int); 198cd6484e1SRob Herring void serdev_device_set_flow_control(struct serdev_device *, bool); 1996bdc00d0SStefan Wahren int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t); 200b3f80c8fSSebastian Reichel void serdev_device_wait_until_sent(struct serdev_device *, long); 2015659dab2SSebastian Reichel int serdev_device_get_tiocm(struct serdev_device *); 2025659dab2SSebastian Reichel int serdev_device_set_tiocm(struct serdev_device *, int, int); 2036fe729c4SAndrey Smirnov void serdev_device_write_wakeup(struct serdev_device *); 2046fe729c4SAndrey Smirnov int serdev_device_write(struct serdev_device *, const unsigned char *, size_t, unsigned long); 205cd6484e1SRob Herring void serdev_device_write_flush(struct serdev_device *); 206cd6484e1SRob Herring int serdev_device_write_room(struct serdev_device *); 207cd6484e1SRob Herring 208cd6484e1SRob Herring /* 209cd6484e1SRob Herring * serdev device driver functions 210cd6484e1SRob Herring */ 211cd6484e1SRob Herring int __serdev_device_driver_register(struct serdev_device_driver *, struct module *); 212cd6484e1SRob Herring #define serdev_device_driver_register(sdrv) \ 213cd6484e1SRob Herring __serdev_device_driver_register(sdrv, THIS_MODULE) 214cd6484e1SRob Herring 215cd6484e1SRob Herring /** 216cd6484e1SRob Herring * serdev_device_driver_unregister() - unregister an serdev client driver 217cd6484e1SRob Herring * @sdrv: the driver to unregister 218cd6484e1SRob Herring */ 219cd6484e1SRob Herring static inline void serdev_device_driver_unregister(struct serdev_device_driver *sdrv) 220cd6484e1SRob Herring { 221cd6484e1SRob Herring if (sdrv) 222cd6484e1SRob Herring driver_unregister(&sdrv->driver); 223cd6484e1SRob Herring } 224cd6484e1SRob Herring 225cd6484e1SRob Herring #define module_serdev_device_driver(__serdev_device_driver) \ 226cd6484e1SRob Herring module_driver(__serdev_device_driver, serdev_device_driver_register, \ 227cd6484e1SRob Herring serdev_device_driver_unregister) 228cd6484e1SRob Herring 229cd6484e1SRob Herring #else 230cd6484e1SRob Herring 231cd6484e1SRob Herring static inline int serdev_device_open(struct serdev_device *sdev) 232cd6484e1SRob Herring { 233cd6484e1SRob Herring return -ENODEV; 234cd6484e1SRob Herring } 235cd6484e1SRob Herring static inline void serdev_device_close(struct serdev_device *sdev) {} 236cd6484e1SRob Herring static inline unsigned int serdev_device_set_baudrate(struct serdev_device *sdev, unsigned int baudrate) 237cd6484e1SRob Herring { 238cd6484e1SRob Herring return 0; 239cd6484e1SRob Herring } 240cd6484e1SRob Herring static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {} 2416bdc00d0SStefan Wahren static inline int serdev_device_write_buf(struct serdev_device *serdev, 2426bdc00d0SStefan Wahren const unsigned char *buf, 2436bdc00d0SStefan Wahren size_t count) 2446bdc00d0SStefan Wahren { 2456bdc00d0SStefan Wahren return -ENODEV; 2466bdc00d0SStefan Wahren } 247b3f80c8fSSebastian Reichel static inline void serdev_device_wait_until_sent(struct serdev_device *sdev, long timeout) {} 2485659dab2SSebastian Reichel static inline int serdev_device_get_tiocm(struct serdev_device *serdev) 2495659dab2SSebastian Reichel { 2505659dab2SSebastian Reichel return -ENOTSUPP; 2515659dab2SSebastian Reichel } 2525659dab2SSebastian Reichel static inline int serdev_device_set_tiocm(struct serdev_device *serdev, int set, int clear) 2535659dab2SSebastian Reichel { 2545659dab2SSebastian Reichel return -ENOTSUPP; 2555659dab2SSebastian Reichel } 2566fe729c4SAndrey Smirnov static inline int serdev_device_write(struct serdev_device *sdev, const unsigned char *buf, 2576fe729c4SAndrey Smirnov size_t count, unsigned long timeout) 258cd6484e1SRob Herring { 259cd6484e1SRob Herring return -ENODEV; 260cd6484e1SRob Herring } 261cd6484e1SRob Herring static inline void serdev_device_write_flush(struct serdev_device *sdev) {} 262cd6484e1SRob Herring static inline int serdev_device_write_room(struct serdev_device *sdev) 263cd6484e1SRob Herring { 264cd6484e1SRob Herring return 0; 265cd6484e1SRob Herring } 266cd6484e1SRob Herring 267cd6484e1SRob Herring #define serdev_device_driver_register(x) 268cd6484e1SRob Herring #define serdev_device_driver_unregister(x) 269cd6484e1SRob Herring 270cd6484e1SRob Herring #endif /* CONFIG_SERIAL_DEV_BUS */ 271cd6484e1SRob Herring 272756db778SSebastian Reichel static inline bool serdev_device_get_cts(struct serdev_device *serdev) 273756db778SSebastian Reichel { 274756db778SSebastian Reichel int status = serdev_device_get_tiocm(serdev); 275756db778SSebastian Reichel return !!(status & TIOCM_CTS); 276756db778SSebastian Reichel } 277756db778SSebastian Reichel 278756db778SSebastian Reichel static inline int serdev_device_wait_for_cts(struct serdev_device *serdev, bool state, int timeout_ms) 279756db778SSebastian Reichel { 280756db778SSebastian Reichel unsigned long timeout; 281756db778SSebastian Reichel bool signal; 282756db778SSebastian Reichel 283756db778SSebastian Reichel timeout = jiffies + msecs_to_jiffies(timeout_ms); 284756db778SSebastian Reichel while (time_is_after_jiffies(timeout)) { 285756db778SSebastian Reichel signal = serdev_device_get_cts(serdev); 286756db778SSebastian Reichel if (signal == state) 287756db778SSebastian Reichel return 0; 288756db778SSebastian Reichel usleep_range(1000, 2000); 289756db778SSebastian Reichel } 290756db778SSebastian Reichel 291756db778SSebastian Reichel return -ETIMEDOUT; 292756db778SSebastian Reichel } 293756db778SSebastian Reichel 294756db778SSebastian Reichel static inline int serdev_device_set_rts(struct serdev_device *serdev, bool enable) 295756db778SSebastian Reichel { 296756db778SSebastian Reichel if (enable) 297756db778SSebastian Reichel return serdev_device_set_tiocm(serdev, TIOCM_RTS, 0); 298756db778SSebastian Reichel else 299756db778SSebastian Reichel return serdev_device_set_tiocm(serdev, 0, TIOCM_RTS); 300756db778SSebastian Reichel } 301756db778SSebastian Reichel 302bed35c6dSRob Herring /* 303bed35c6dSRob Herring * serdev hooks into TTY core 304bed35c6dSRob Herring */ 305bed35c6dSRob Herring struct tty_port; 306bed35c6dSRob Herring struct tty_driver; 307bed35c6dSRob Herring 308bed35c6dSRob Herring #ifdef CONFIG_SERIAL_DEV_CTRL_TTYPORT 309bed35c6dSRob Herring struct device *serdev_tty_port_register(struct tty_port *port, 310bed35c6dSRob Herring struct device *parent, 311bed35c6dSRob Herring struct tty_driver *drv, int idx); 3128cde11b2SJohan Hovold int serdev_tty_port_unregister(struct tty_port *port); 313bed35c6dSRob Herring #else 314bed35c6dSRob Herring static inline struct device *serdev_tty_port_register(struct tty_port *port, 315bed35c6dSRob Herring struct device *parent, 316bed35c6dSRob Herring struct tty_driver *drv, int idx) 317bed35c6dSRob Herring { 318bed35c6dSRob Herring return ERR_PTR(-ENODEV); 319bed35c6dSRob Herring } 3208cde11b2SJohan Hovold static inline int serdev_tty_port_unregister(struct tty_port *port) 3218cde11b2SJohan Hovold { 3228cde11b2SJohan Hovold return -ENODEV; 3238cde11b2SJohan Hovold } 324bed35c6dSRob Herring #endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */ 325bed35c6dSRob Herring 326cd6484e1SRob Herring #endif /*_LINUX_SERDEV_H */ 327