1 /* 2 * HSI core header file. 3 * 4 * Copyright (C) 2010 Nokia Corporation. All rights reserved. 5 * 6 * Contact: Carlos Chinea <carlos.chinea@nokia.com> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * version 2 as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA 21 */ 22 23 #ifndef __LINUX_HSI_H__ 24 #define __LINUX_HSI_H__ 25 26 #include <linux/device.h> 27 #include <linux/mutex.h> 28 #include <linux/scatterlist.h> 29 #include <linux/list.h> 30 #include <linux/module.h> 31 #include <linux/notifier.h> 32 33 /* HSI message ttype */ 34 #define HSI_MSG_READ 0 35 #define HSI_MSG_WRITE 1 36 37 /* HSI configuration values */ 38 enum { 39 HSI_MODE_STREAM = 1, 40 HSI_MODE_FRAME, 41 }; 42 43 enum { 44 HSI_FLOW_SYNC, /* Synchronized flow */ 45 HSI_FLOW_PIPE, /* Pipelined flow */ 46 }; 47 48 enum { 49 HSI_ARB_RR, /* Round-robin arbitration */ 50 HSI_ARB_PRIO, /* Channel priority arbitration */ 51 }; 52 53 #define HSI_MAX_CHANNELS 16 54 55 /* HSI message status codes */ 56 enum { 57 HSI_STATUS_COMPLETED, /* Message transfer is completed */ 58 HSI_STATUS_PENDING, /* Message pending to be read/write (POLL) */ 59 HSI_STATUS_PROCEEDING, /* Message transfer is ongoing */ 60 HSI_STATUS_QUEUED, /* Message waiting to be served */ 61 HSI_STATUS_ERROR, /* Error when message transfer was ongoing */ 62 }; 63 64 /* HSI port event codes */ 65 enum { 66 HSI_EVENT_START_RX, 67 HSI_EVENT_STOP_RX, 68 }; 69 70 /** 71 * struct hsi_channel - channel resource used by the hsi clients 72 * @id: Channel number 73 * @name: Channel name 74 */ 75 struct hsi_channel { 76 unsigned int id; 77 const char *name; 78 }; 79 80 /** 81 * struct hsi_config - Configuration for RX/TX HSI modules 82 * @mode: Bit transmission mode (STREAM or FRAME) 83 * @channels: Channel resources used by the client 84 * @num_channels: Number of channel resources 85 * @num_hw_channels: Number of channels the transceiver is configured for [1..16] 86 * @speed: Max bit transmission speed (Kbit/s) 87 * @flow: RX flow type (SYNCHRONIZED or PIPELINE) 88 * @arb_mode: Arbitration mode for TX frame (Round robin, priority) 89 */ 90 struct hsi_config { 91 unsigned int mode; 92 struct hsi_channel *channels; 93 unsigned int num_channels; 94 unsigned int num_hw_channels; 95 unsigned int speed; 96 union { 97 unsigned int flow; /* RX only */ 98 unsigned int arb_mode; /* TX only */ 99 }; 100 }; 101 102 /** 103 * struct hsi_board_info - HSI client board info 104 * @name: Name for the HSI device 105 * @hsi_id: HSI controller id where the client sits 106 * @port: Port number in the controller where the client sits 107 * @tx_cfg: HSI TX configuration 108 * @rx_cfg: HSI RX configuration 109 * @platform_data: Platform related data 110 * @archdata: Architecture-dependent device data 111 */ 112 struct hsi_board_info { 113 const char *name; 114 unsigned int hsi_id; 115 unsigned int port; 116 struct hsi_config tx_cfg; 117 struct hsi_config rx_cfg; 118 void *platform_data; 119 struct dev_archdata *archdata; 120 }; 121 122 #ifdef CONFIG_HSI_BOARDINFO 123 extern int hsi_register_board_info(struct hsi_board_info const *info, 124 unsigned int len); 125 #else 126 static inline int hsi_register_board_info(struct hsi_board_info const *info, 127 unsigned int len) 128 { 129 return 0; 130 } 131 #endif /* CONFIG_HSI_BOARDINFO */ 132 133 /** 134 * struct hsi_client - HSI client attached to an HSI port 135 * @device: Driver model representation of the device 136 * @tx_cfg: HSI TX configuration 137 * @rx_cfg: HSI RX configuration 138 */ 139 struct hsi_client { 140 struct device device; 141 struct hsi_config tx_cfg; 142 struct hsi_config rx_cfg; 143 /* private: */ 144 void (*ehandler)(struct hsi_client *, unsigned long); 145 unsigned int pclaimed:1; 146 struct notifier_block nb; 147 }; 148 149 #define to_hsi_client(dev) container_of(dev, struct hsi_client, device) 150 151 static inline void hsi_client_set_drvdata(struct hsi_client *cl, void *data) 152 { 153 dev_set_drvdata(&cl->device, data); 154 } 155 156 static inline void *hsi_client_drvdata(struct hsi_client *cl) 157 { 158 return dev_get_drvdata(&cl->device); 159 } 160 161 int hsi_register_port_event(struct hsi_client *cl, 162 void (*handler)(struct hsi_client *, unsigned long)); 163 int hsi_unregister_port_event(struct hsi_client *cl); 164 165 /** 166 * struct hsi_client_driver - Driver associated to an HSI client 167 * @driver: Driver model representation of the driver 168 */ 169 struct hsi_client_driver { 170 struct device_driver driver; 171 }; 172 173 #define to_hsi_client_driver(drv) container_of(drv, struct hsi_client_driver,\ 174 driver) 175 176 int hsi_register_client_driver(struct hsi_client_driver *drv); 177 178 static inline void hsi_unregister_client_driver(struct hsi_client_driver *drv) 179 { 180 driver_unregister(&drv->driver); 181 } 182 183 /** 184 * struct hsi_msg - HSI message descriptor 185 * @link: Free to use by the current descriptor owner 186 * @cl: HSI device client that issues the transfer 187 * @sgt: Head of the scatterlist array 188 * @context: Client context data associated to the transfer 189 * @complete: Transfer completion callback 190 * @destructor: Destructor to free resources when flushing 191 * @status: Status of the transfer when completed 192 * @actual_len: Actual length of data transferred on completion 193 * @channel: Channel were to TX/RX the message 194 * @ttype: Transfer type (TX if set, RX otherwise) 195 * @break_frame: if true HSI will send/receive a break frame. Data buffers are 196 * ignored in the request. 197 */ 198 struct hsi_msg { 199 struct list_head link; 200 struct hsi_client *cl; 201 struct sg_table sgt; 202 void *context; 203 204 void (*complete)(struct hsi_msg *msg); 205 void (*destructor)(struct hsi_msg *msg); 206 207 int status; 208 unsigned int actual_len; 209 unsigned int channel; 210 unsigned int ttype:1; 211 unsigned int break_frame:1; 212 }; 213 214 struct hsi_msg *hsi_alloc_msg(unsigned int n_frag, gfp_t flags); 215 void hsi_free_msg(struct hsi_msg *msg); 216 217 /** 218 * struct hsi_port - HSI port device 219 * @device: Driver model representation of the device 220 * @tx_cfg: Current TX path configuration 221 * @rx_cfg: Current RX path configuration 222 * @num: Port number 223 * @shared: Set when port can be shared by different clients 224 * @claimed: Reference count of clients which claimed the port 225 * @lock: Serialize port claim 226 * @async: Asynchronous transfer callback 227 * @setup: Callback to set the HSI client configuration 228 * @flush: Callback to clean the HW state and destroy all pending transfers 229 * @start_tx: Callback to inform that a client wants to TX data 230 * @stop_tx: Callback to inform that a client no longer wishes to TX data 231 * @release: Callback to inform that a client no longer uses the port 232 * @n_head: Notifier chain for signaling port events to the clients. 233 */ 234 struct hsi_port { 235 struct device device; 236 struct hsi_config tx_cfg; 237 struct hsi_config rx_cfg; 238 unsigned int num; 239 unsigned int shared:1; 240 int claimed; 241 struct mutex lock; 242 int (*async)(struct hsi_msg *msg); 243 int (*setup)(struct hsi_client *cl); 244 int (*flush)(struct hsi_client *cl); 245 int (*start_tx)(struct hsi_client *cl); 246 int (*stop_tx)(struct hsi_client *cl); 247 int (*release)(struct hsi_client *cl); 248 /* private */ 249 struct blocking_notifier_head n_head; 250 }; 251 252 #define to_hsi_port(dev) container_of(dev, struct hsi_port, device) 253 #define hsi_get_port(cl) to_hsi_port((cl)->device.parent) 254 255 int hsi_event(struct hsi_port *port, unsigned long event); 256 int hsi_claim_port(struct hsi_client *cl, unsigned int share); 257 void hsi_release_port(struct hsi_client *cl); 258 259 static inline int hsi_port_claimed(struct hsi_client *cl) 260 { 261 return cl->pclaimed; 262 } 263 264 static inline void hsi_port_set_drvdata(struct hsi_port *port, void *data) 265 { 266 dev_set_drvdata(&port->device, data); 267 } 268 269 static inline void *hsi_port_drvdata(struct hsi_port *port) 270 { 271 return dev_get_drvdata(&port->device); 272 } 273 274 /** 275 * struct hsi_controller - HSI controller device 276 * @device: Driver model representation of the device 277 * @owner: Pointer to the module owning the controller 278 * @id: HSI controller ID 279 * @num_ports: Number of ports in the HSI controller 280 * @port: Array of HSI ports 281 */ 282 struct hsi_controller { 283 struct device device; 284 struct module *owner; 285 unsigned int id; 286 unsigned int num_ports; 287 struct hsi_port **port; 288 }; 289 290 #define to_hsi_controller(dev) container_of(dev, struct hsi_controller, device) 291 292 struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags); 293 void hsi_put_controller(struct hsi_controller *hsi); 294 int hsi_register_controller(struct hsi_controller *hsi); 295 void hsi_unregister_controller(struct hsi_controller *hsi); 296 struct hsi_client *hsi_new_client(struct hsi_port *port, 297 struct hsi_board_info *info); 298 int hsi_remove_client(struct device *dev, void *data); 299 void hsi_port_unregister_clients(struct hsi_port *port); 300 301 #ifdef CONFIG_OF 302 void hsi_add_clients_from_dt(struct hsi_port *port, 303 struct device_node *clients); 304 #else 305 static inline void hsi_add_clients_from_dt(struct hsi_port *port, 306 struct device_node *clients) 307 { 308 return; 309 } 310 #endif 311 312 static inline void hsi_controller_set_drvdata(struct hsi_controller *hsi, 313 void *data) 314 { 315 dev_set_drvdata(&hsi->device, data); 316 } 317 318 static inline void *hsi_controller_drvdata(struct hsi_controller *hsi) 319 { 320 return dev_get_drvdata(&hsi->device); 321 } 322 323 static inline struct hsi_port *hsi_find_port_num(struct hsi_controller *hsi, 324 unsigned int num) 325 { 326 return (num < hsi->num_ports) ? hsi->port[num] : NULL; 327 } 328 329 /* 330 * API for HSI clients 331 */ 332 int hsi_async(struct hsi_client *cl, struct hsi_msg *msg); 333 334 int hsi_get_channel_id_by_name(struct hsi_client *cl, char *name); 335 336 /** 337 * hsi_id - Get HSI controller ID associated to a client 338 * @cl: Pointer to a HSI client 339 * 340 * Return the controller id where the client is attached to 341 */ 342 static inline unsigned int hsi_id(struct hsi_client *cl) 343 { 344 return to_hsi_controller(cl->device.parent->parent)->id; 345 } 346 347 /** 348 * hsi_port_id - Gets the port number a client is attached to 349 * @cl: Pointer to HSI client 350 * 351 * Return the port number associated to the client 352 */ 353 static inline unsigned int hsi_port_id(struct hsi_client *cl) 354 { 355 return to_hsi_port(cl->device.parent)->num; 356 } 357 358 /** 359 * hsi_setup - Configure the client's port 360 * @cl: Pointer to the HSI client 361 * 362 * When sharing ports, clients should either relay on a single 363 * client setup or have the same setup for all of them. 364 * 365 * Return -errno on failure, 0 on success 366 */ 367 static inline int hsi_setup(struct hsi_client *cl) 368 { 369 if (!hsi_port_claimed(cl)) 370 return -EACCES; 371 return hsi_get_port(cl)->setup(cl); 372 } 373 374 /** 375 * hsi_flush - Flush all pending transactions on the client's port 376 * @cl: Pointer to the HSI client 377 * 378 * This function will destroy all pending hsi_msg in the port and reset 379 * the HW port so it is ready to receive and transmit from a clean state. 380 * 381 * Return -errno on failure, 0 on success 382 */ 383 static inline int hsi_flush(struct hsi_client *cl) 384 { 385 if (!hsi_port_claimed(cl)) 386 return -EACCES; 387 return hsi_get_port(cl)->flush(cl); 388 } 389 390 /** 391 * hsi_async_read - Submit a read transfer 392 * @cl: Pointer to the HSI client 393 * @msg: HSI message descriptor of the transfer 394 * 395 * Return -errno on failure, 0 on success 396 */ 397 static inline int hsi_async_read(struct hsi_client *cl, struct hsi_msg *msg) 398 { 399 msg->ttype = HSI_MSG_READ; 400 return hsi_async(cl, msg); 401 } 402 403 /** 404 * hsi_async_write - Submit a write transfer 405 * @cl: Pointer to the HSI client 406 * @msg: HSI message descriptor of the transfer 407 * 408 * Return -errno on failure, 0 on success 409 */ 410 static inline int hsi_async_write(struct hsi_client *cl, struct hsi_msg *msg) 411 { 412 msg->ttype = HSI_MSG_WRITE; 413 return hsi_async(cl, msg); 414 } 415 416 /** 417 * hsi_start_tx - Signal the port that the client wants to start a TX 418 * @cl: Pointer to the HSI client 419 * 420 * Return -errno on failure, 0 on success 421 */ 422 static inline int hsi_start_tx(struct hsi_client *cl) 423 { 424 if (!hsi_port_claimed(cl)) 425 return -EACCES; 426 return hsi_get_port(cl)->start_tx(cl); 427 } 428 429 /** 430 * hsi_stop_tx - Signal the port that the client no longer wants to transmit 431 * @cl: Pointer to the HSI client 432 * 433 * Return -errno on failure, 0 on success 434 */ 435 static inline int hsi_stop_tx(struct hsi_client *cl) 436 { 437 if (!hsi_port_claimed(cl)) 438 return -EACCES; 439 return hsi_get_port(cl)->stop_tx(cl); 440 } 441 #endif /* __LINUX_HSI_H__ */ 442