| /** |
| * TSIF driver |
| * |
| * Kernel API |
| * |
| * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 and |
| * only version 2 as published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| */ |
| #ifndef _TSIF_API_H_ |
| #define _TSIF_API_H_ |
| /** |
| * Theory of operation |
| * |
| * TSIF driver maintains internal cyclic data buffer where |
| * received TSIF packets are stored. Size of buffer, in packets, |
| * and its address, may be obtained by tsif_get_info(). |
| * |
| * TSIF stream delivered to the client that should register with |
| * TSIF driver using tsif_attach() |
| * |
| * Producer-consumer pattern used. TSIF driver act as producer, |
| * writing data to the buffer; clientis consumer. |
| * 2 indexes maintained by the TSIF driver: |
| * - wi (write index) points to the next item to be written by |
| * TSIF |
| * - ri (read index) points to the next item available for read |
| * by the client. |
| * Write index advanced by the TSIF driver when new data |
| * received; |
| * Read index advanced only when client tell so to the TSIF |
| * driver by tsif_reclaim_packets() |
| * |
| * Consumer may directly access data TSIF buffer between ri and |
| * wi. When ri==wi, buffer is empty. |
| * |
| * TSIF driver notifies client about any change by calling |
| * notify function. Client should use tsif_get_state() to query |
| * new state. |
| */ |
| |
| /* bytes in TSIF packet. not customizable */ |
| #define TSIF_PKT_SIZE (192) |
| |
| /** |
| * tsif_pkt_status - get TSIF packet status |
| * |
| * @pkt: TSIF packet location |
| * |
| * Return last DWORD of packet, containing status. |
| * Status dword consists of: |
| * - 3 low bytes TTS |
| * - 1 byte (last byte of packet) with status bits |
| */ |
| static inline u32 tsif_pkt_status(void *pkt) |
| { |
| u32 *x = pkt; |
| return x[TSIF_PKT_SIZE / sizeof(u32) - 1]; |
| } |
| |
| /** |
| * Status dword parts for status returned by @tsif_pkt_status |
| */ |
| #define TSIF_STATUS_TTS(x) ((x) & 0xffffff) |
| #define TSIF_STATUS_VALID(x) ((x) & (1<<24)) |
| #define TSIF_STATUS_FIRST(x) ((x) & (1<<25)) |
| #define TSIF_STATUS_OVFLW(x) ((x) & (1<<26)) |
| #define TSIF_STATUS_ERROR(x) ((x) & (1<<27)) |
| #define TSIF_STATUS_NULL(x) ((x) & (1<<28)) |
| #define TSIF_STATUS_TIMEO(x) ((x) & (1<<30)) |
| |
| /** |
| * enum tsif_state - TSIF device state |
| * @tsif_state_stopped: Idle state, data acquisition not running |
| * @tsif_state_running: Data acquisition in progress |
| * @tsif_state_flushing: Device is flushing |
| * |
| * State transition diagram: |
| * |
| * init -> tsif_state_stopped |
| * |
| * tsif_state_stopped: |
| * - open -> tsif_state_running |
| * |
| * tsif_state_running: |
| * - close -> tsif_state_flushing |
| * |
| * tsif_state_flushing: |
| * - flushed -> tsif_state_stopped |
| */ |
| enum tsif_state { |
| tsif_state_stopped = 0, |
| tsif_state_running = 1, |
| tsif_state_flushing = 2, |
| tsif_state_error = 3, |
| }; |
| |
| /** |
| * tsif_get_active - return active tsif hardware instance |
| * |
| * Return TSIF instance to use (selected by CONFIG_MSM_USE_TSIF1) |
| */ |
| int tsif_get_active(void); |
| |
| /** |
| * tsif_attach - Attach to the device. |
| * @id: TSIF device ID, used to identify TSIF instance. |
| * @notify: client callback, called when |
| * any client visible TSIF state changed. |
| * This includes new data available and device state change |
| * @data: client data, will be passed to @notify |
| * |
| * Return TSIF cookie or error code |
| * |
| * Should be called prior to any other tsif_XXX function. |
| */ |
| void *tsif_attach(int id, void (*notify)(void *client_data), void *client_data); |
| |
| /** |
| * tsif_detach - detach from device |
| * @cookie: TSIF cookie previously obtained with tsif_attach() |
| */ |
| void tsif_detach(void *cookie); |
| |
| /** |
| * tsif_get_info - get data buffer info |
| * @cookie: TSIF cookie previously obtained with tsif_attach() |
| * @pdata: if not NULL, TSIF data buffer will be stored there |
| * @psize: if not NULL, TSIF data buffer size, in packets, |
| * will be stored there |
| * |
| * Data buffer information should be queried after each tsif_start() before |
| * using data; since data buffer will be re-allocated on tsif_start() |
| */ |
| void tsif_get_info(void *cookie, void **pdata, int *psize); |
| |
| /** |
| * tsif_set_mode - set TSIF mode |
| * @cookie: TSIF cookie previously obtained with tsif_attach() |
| * @mode: desired mode of operation |
| * |
| * Return error code |
| * |
| * Mode may be changed only when TSIF device is stopped. |
| */ |
| int tsif_set_mode(void *cookie, int mode); |
| |
| /** |
| * tsif_set_time_limit - set TSIF time limit |
| * @cookie: TSIF cookie previously obtained with tsif_attach() |
| * @value: desired time limit, 0 to disable |
| * |
| * Return error code |
| * |
| * Time limit may be changed only when TSIF device is stopped. |
| */ |
| int tsif_set_time_limit(void *cookie, u32 value); |
| |
| /** |
| * tsif_set_buf_config - configure data buffer |
| * |
| * @cookie: TSIF cookie previously obtained with tsif_attach() |
| * @pkts_in_chunk: requested number of packets per chunk |
| * @chunks_in_buf: requested number of chunks in buffer |
| * |
| * Return error code |
| * |
| * Parameter selection criteria: |
| * |
| * - @pkts_in_chunk defines size of DMA transfer and, in turn, time between |
| * consecutive DMA transfers. Increase @pkts_in_chunk reduces chance for |
| * hardware overflow. If TSIF stats reports overflows, increase it. |
| * |
| * - @chunks_in_buf * @pkts_in_chunk defines total buffer size. Increase this |
| * parameter if client latency is large and TSIF reports "soft drop" in its |
| * stats |
| */ |
| int tsif_set_buf_config(void *cookie, u32 pkts_in_chunk, u32 chunks_in_buf); |
| |
| /** |
| * tsif_get_state - query current data buffer information |
| * @cookie: TSIF cookie previously obtained with tsif_attach() |
| * @ri: if not NULL, read index will be stored here |
| * @wi: if not NULL, write index will be stored here |
| * @state: if not NULL, state will be stored here |
| */ |
| void tsif_get_state(void *cookie, int *ri, int *wi, enum tsif_state *state); |
| |
| /** |
| * tsif_set_clk_inverse - set whether to inverse the clock signal. |
| * @cookie: TSIF cookie previously obtained with tsif_attach() |
| * @inverse: 1 to inverse the clock, 0 otherwise. Default is 0. |
| * |
| * Return error code |
| * |
| * Setting may be changed only when TSIF device is stopped. |
| */ |
| int tsif_set_clk_inverse(void *cookie, int inverse); |
| |
| /** |
| * tsif_set_data_inverse - set whether to inverse the data signal. |
| * @cookie: TSIF cookie previously obtained with tsif_attach() |
| * @inverse: 1 to inverse the clock, 0 otherwise. Default is 0. |
| * |
| * Return error code |
| * |
| * Setting may be changed only when TSIF device is stopped. |
| */ |
| int tsif_set_data_inverse(void *cookie, int inverse); |
| |
| /** |
| * tsif_set_sync_inverse - set whether to inverse the sync signal. |
| * @cookie: TSIF cookie previously obtained with tsif_attach() |
| * @inverse: 1 to inverse the clock, 0 otherwise. Default is 0. |
| * |
| * Return error code |
| * |
| * Setting may be changed only when TSIF device is stopped. |
| */ |
| int tsif_set_sync_inverse(void *cookie, int inverse); |
| |
| /** |
| * tsif_set_enable_inverse - set whether to inverse the enable signal. |
| * @cookie: TSIF cookie previously obtained with tsif_attach() |
| * @inverse: 1 to inverse the clock, 0 otherwise. Default is 0. |
| * |
| * Return error code |
| * |
| * Setting may be changed only when TSIF device is stopped. |
| */ |
| int tsif_set_enable_inverse(void *cookie, int inverse); |
| |
| /** |
| * tsif_start - start data acquisition |
| * @cookie: TSIF cookie previously obtained with tsif_attach() |
| * |
| * Return error code |
| */ |
| int tsif_start(void *cookie); |
| |
| /** |
| * tsif_stop - stop data acquisition |
| * @cookie: TSIF cookie previously obtained with tsif_attach() |
| * |
| * Data buffer allocated during this function call; thus client should |
| * query data buffer info using tsif_get_info() and reset its data pointers. |
| */ |
| void tsif_stop(void *cookie); |
| |
| /** |
| * tsif_get_ref_clk_counter - return the TSIF clock reference (TCR) counter. |
| * @cookie: TSIF cookie previously obtained with tsif_attach() |
| * @tcr_counter: the value of TCR counter |
| * |
| * Return error code |
| * |
| * TCR increments at a rate equal to 27 MHz/256 = 105.47 kHz. |
| */ |
| int tsif_get_ref_clk_counter(void *cookie, u32 *tcr_counter); |
| |
| /** |
| * tsif_reclaim_packets - inform that buffer space may be reclaimed |
| * @cookie: TSIF cookie previously obtained with tsif_attach() |
| * @ri: new value for read index |
| */ |
| void tsif_reclaim_packets(void *cookie, int ri); |
| |
| #endif /* _TSIF_API_H_ */ |
| |