/** * 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_ */