fmdrv.h 6.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
/*
 *  FM Driver for Connectivity chip of Texas Instruments.
 *
 *  Common header for all FM driver sub-modules.
 *
 *  Copyright (C) 2011 Texas Instruments
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License 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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#ifndef _FM_DRV_H
#define _FM_DRV_H

#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <linux/timer.h>
#include <linux/version.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>

#define FM_DRV_VERSION            "0.10"
/* Should match with FM_DRV_VERSION */
#define FM_DRV_RADIO_VERSION      KERNEL_VERSION(0, 0, 1)
#define FM_DRV_NAME               "ti_fmdrv"
#define FM_DRV_CARD_SHORT_NAME    "TI FM Radio"
#define FM_DRV_CARD_LONG_NAME     "Texas Instruments FM Radio"

/* Flag info */
#define FM_INTTASK_RUNNING            0
#define FM_INTTASK_SCHEDULE_PENDING   1
#define FM_FW_DW_INPROGRESS     2
#define FM_CORE_READY                 3
#define FM_CORE_TRANSPORT_READY       4
#define FM_AF_SWITCH_INPROGRESS	      5
#define FM_CORE_TX_XMITING	      6

#define FM_TUNE_COMPLETE	      0x1
#define FM_BAND_LIMIT		      0x2

#define FM_DRV_TX_TIMEOUT      (5*HZ)	/* 5 seconds */
#define FM_DRV_RX_SEEK_TIMEOUT (20*HZ)	/* 20 seconds */

#define NO_OF_ENTRIES_IN_ARRAY(array) (sizeof(array) / sizeof(array[0]))

#define fmerr(format, ...) \
	printk(KERN_ERR "fmdrv: " format, ## __VA_ARGS__)
#define fmwarn(format, ...) \
	printk(KERN_WARNING "fmdrv: " format, ##__VA_ARGS__)
#ifdef DEBUG
#define fmdbg(format, ...) \
	printk(KERN_DEBUG "fmdrv: " format, ## __VA_ARGS__)
#else /* DEBUG */
#define fmdbg(format, ...)
#endif
enum {
	FM_MODE_OFF,
	FM_MODE_TX,
	FM_MODE_RX,
	FM_MODE_ENTRY_MAX
};

#define FM_RX_RDS_INFO_FIELD_MAX	8	/* 4 Group * 2 Bytes */

/* RX RDS data format */
struct fm_rdsdata_format {
	union {
		struct {
			u8 buff[FM_RX_RDS_INFO_FIELD_MAX];
		} groupdatabuff;
		struct {
			u16 pidata;
			u8 blk_b[2];
			u8 blk_c[2];
			u8 blk_d[2];
		} groupgeneral;
		struct {
			u16 pidata;
			u8 blk_b[2];
			u8 af[2];
			u8 ps[2];
		} group0A;
		struct {
			u16 pi[2];
			u8 blk_b[2];
			u8 ps[2];
		} group0B;
	} data;
};

/* FM region (Europe/US, Japan) info */
struct region_info {
	u32 chanl_space;
	u32 bot_freq;
	u32 top_freq;
	u8 fm_band;
};
struct fmdev;
typedef void (*int_handler_prototype) (struct fmdev *);

/* FM Interrupt processing related info */
struct fm_irq {
	u8 stage;
	u16 flag;	/* FM interrupt flag */
	u16 mask;	/* FM interrupt mask */
	/* Interrupt process timeout handler */
	struct timer_list timer;
	u8 retry;
	int_handler_prototype *handlers;
};

/* RDS info */
struct fm_rds {
	u8 flag;	/* RX RDS on/off status */
	u8 last_blk_idx;	/* Last received RDS block */

	/* RDS buffer */
	wait_queue_head_t read_queue;
	u32 buf_size;	/* Size is always multiple of 3 */
	u32 wr_idx;
	u32 rd_idx;
	u8 *buff;
};

#define FM_RDS_MAX_AF_LIST		25

/*
 * Current RX channel Alternate Frequency cache.
 * This info is used to switch to other freq (AF)
 * when current channel signal strengh is below RSSI threshold.
 */
struct tuned_station_info {
	u16 picode;
	u32 af_cache[FM_RDS_MAX_AF_LIST];
	u8 afcache_size;
	u8 af_list_max;
};

/* FM RX mode info */
struct fm_rx {
	struct region_info region;	/* Current selected band */
	u32 freq;	/* Current RX frquency */
	u8 mute_mode;	/* Current mute mode */
	u8 deemphasis_mode; /* Current deemphasis mode */
	/* RF dependent soft mute mode */
	u8 rf_depend_mute;
	u16 volume;	/* Current volume level */
	u16 rssi_threshold;	/* Current RSSI threshold level */
	/* Holds the index of the current AF jump */
	u8 afjump_idx;
	/* Will hold the frequency before the jump */
	u32 freq_before_jump;
	u8 rds_mode;	/* RDS operation mode (RDS/RDBS) */
	u8 af_mode;	/* Alternate frequency on/off */
	struct tuned_station_info stat_info;
	struct fm_rds rds;
};

#define FMTX_RDS_TXT_STR_SIZE	25
/*
 * FM TX RDS data
 *
 * @ text_type: is the text following PS or RT
 * @ text: radio text string which could either be PS or RT
 * @ af_freq: alternate frequency for Tx
 * TODO: to be declared in application
 */
struct tx_rds {
	u8 text_type;
	u8 text[FMTX_RDS_TXT_STR_SIZE];
	u8 flag;
	u32 af_freq;
};
/*
 * FM TX global data
 *
 * @ pwr_lvl: Power Level of the Transmission from mixer control
 * @ xmit_state: Transmission state = Updated locally upon Start/Stop
 * @ audio_io: i2S/Analog
 * @ tx_frq: Transmission frequency
 */
struct fmtx_data {
	u8 pwr_lvl;
	u8 xmit_state;
	u8 audio_io;
	u8 region;
	u16 aud_mode;
	u32 preemph;
	u32 tx_frq;
	struct tx_rds rds;
};

/* FM driver operation structure */
struct fmdev {
	struct video_device *radio_dev;	/* V4L2 video device pointer */
	struct snd_card *card;	/* Card which holds FM mixer controls */
	u16 asci_id;
	spinlock_t rds_buff_lock; /* To protect access to RDS buffer */
	spinlock_t resp_skb_lock; /* To protect access to received SKB */

	long flag;		/*  FM driver state machine info */
	u8 streg_cbdata; /* status of ST registration */

	struct sk_buff_head rx_q;	/* RX queue */
	struct tasklet_struct rx_task;	/* RX Tasklet */

	struct sk_buff_head tx_q;	/* TX queue */
	struct tasklet_struct tx_task;	/* TX Tasklet */
	unsigned long last_tx_jiffies;	/* Timestamp of last pkt sent */
	atomic_t tx_cnt;	/* Number of packets can send at a time */

	struct sk_buff *resp_skb;	/* Response from the chip */
	/* Main task completion handler */
	struct completion maintask_comp;
	/* Opcode of last command sent to the chip */
	u8 pre_op;
	/* Handler used for wakeup when response packet is received */
	struct completion *resp_comp;
	struct fm_irq irq_info;
	u8 curr_fmmode; /* Current FM chip mode (TX, RX, OFF) */
	struct fm_rx rx;	/* FM receiver info */
	struct fmtx_data tx_data;

	/* V4L2 ctrl framwork handler*/
	struct v4l2_ctrl_handler ctrl_handler;

	/* For core assisted locking */
	struct mutex mutex;
};
#endif