Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  *  FM Driver for Connectivity chip of Texas Instruments.
0004  *
0005  *  Common header for all FM driver sub-modules.
0006  *
0007  *  Copyright (C) 2011 Texas Instruments
0008  */
0009 
0010 #ifndef _FM_DRV_H
0011 #define _FM_DRV_H
0012 
0013 #include <linux/skbuff.h>
0014 #include <linux/interrupt.h>
0015 #include <sound/core.h>
0016 #include <sound/initval.h>
0017 #include <linux/timer.h>
0018 #include <media/v4l2-ioctl.h>
0019 #include <media/v4l2-common.h>
0020 #include <media/v4l2-device.h>
0021 #include <media/v4l2-ctrls.h>
0022 
0023 #define FM_DRV_VERSION            "0.1.1"
0024 #define FM_DRV_NAME               "ti_fmdrv"
0025 #define FM_DRV_CARD_SHORT_NAME    "TI FM Radio"
0026 #define FM_DRV_CARD_LONG_NAME     "Texas Instruments FM Radio"
0027 
0028 /* Flag info */
0029 #define FM_INTTASK_RUNNING            0
0030 #define FM_INTTASK_SCHEDULE_PENDING   1
0031 #define FM_FW_DW_INPROGRESS     2
0032 #define FM_CORE_READY                 3
0033 #define FM_CORE_TRANSPORT_READY       4
0034 #define FM_AF_SWITCH_INPROGRESS       5
0035 #define FM_CORE_TX_XMITING        6
0036 
0037 #define FM_TUNE_COMPLETE          0x1
0038 #define FM_BAND_LIMIT             0x2
0039 
0040 #define FM_DRV_TX_TIMEOUT      (5*HZ)   /* 5 seconds */
0041 #define FM_DRV_RX_SEEK_TIMEOUT (20*HZ)  /* 20 seconds */
0042 
0043 #define fmerr(format, ...) \
0044     printk(KERN_ERR "fmdrv: " format, ## __VA_ARGS__)
0045 #define fmwarn(format, ...) \
0046     printk(KERN_WARNING "fmdrv: " format, ##__VA_ARGS__)
0047 #ifdef DEBUG
0048 #define fmdbg(format, ...) \
0049     printk(KERN_DEBUG "fmdrv: " format, ## __VA_ARGS__)
0050 #else /* DEBUG */
0051 #define fmdbg(format, ...) do {} while(0)
0052 #endif
0053 enum {
0054     FM_MODE_OFF,
0055     FM_MODE_TX,
0056     FM_MODE_RX,
0057     FM_MODE_ENTRY_MAX
0058 };
0059 
0060 #define FM_RX_RDS_INFO_FIELD_MAX    8   /* 4 Group * 2 Bytes */
0061 
0062 /* RX RDS data format */
0063 struct fm_rdsdata_format {
0064     union {
0065         struct {
0066             u8 buff[FM_RX_RDS_INFO_FIELD_MAX];
0067         } groupdatabuff;
0068         struct {
0069             u16 pidata;
0070             u8 blk_b[2];
0071             u8 blk_c[2];
0072             u8 blk_d[2];
0073         } groupgeneral;
0074         struct {
0075             u16 pidata;
0076             u8 blk_b[2];
0077             u8 af[2];
0078             u8 ps[2];
0079         } group0A;
0080         struct {
0081             u16 pi[2];
0082             u8 blk_b[2];
0083             u8 ps[2];
0084         } group0B;
0085     } data;
0086 };
0087 
0088 /* FM region (Europe/US, Japan) info */
0089 struct region_info {
0090     u32 chanl_space;
0091     u32 bot_freq;
0092     u32 top_freq;
0093     u8 fm_band;
0094 };
0095 struct fmdev;
0096 typedef void (*int_handler_prototype) (struct fmdev *);
0097 
0098 /* FM Interrupt processing related info */
0099 struct fm_irq {
0100     u8 stage;
0101     u16 flag;   /* FM interrupt flag */
0102     u16 mask;   /* FM interrupt mask */
0103     /* Interrupt process timeout handler */
0104     struct timer_list timer;
0105     u8 retry;
0106     int_handler_prototype *handlers;
0107 };
0108 
0109 /* RDS info */
0110 struct fm_rds {
0111     u8 flag;    /* RX RDS on/off status */
0112     u8 last_blk_idx;    /* Last received RDS block */
0113 
0114     /* RDS buffer */
0115     wait_queue_head_t read_queue;
0116     u32 buf_size;   /* Size is always multiple of 3 */
0117     u32 wr_idx;
0118     u32 rd_idx;
0119     u8 *buff;
0120 };
0121 
0122 #define FM_RDS_MAX_AF_LIST      25
0123 
0124 /*
0125  * Current RX channel Alternate Frequency cache.
0126  * This info is used to switch to other freq (AF)
0127  * when current channel signal strength is below RSSI threshold.
0128  */
0129 struct tuned_station_info {
0130     u16 picode;
0131     u32 af_cache[FM_RDS_MAX_AF_LIST];
0132     u8 afcache_size;
0133     u8 af_list_max;
0134 };
0135 
0136 /* FM RX mode info */
0137 struct fm_rx {
0138     struct region_info region;  /* Current selected band */
0139     u32 freq;   /* Current RX frquency */
0140     u8 mute_mode;   /* Current mute mode */
0141     u8 deemphasis_mode; /* Current deemphasis mode */
0142     /* RF dependent soft mute mode */
0143     u8 rf_depend_mute;
0144     u16 volume; /* Current volume level */
0145     u16 rssi_threshold; /* Current RSSI threshold level */
0146     /* Holds the index of the current AF jump */
0147     u8 afjump_idx;
0148     /* Will hold the frequency before the jump */
0149     u32 freq_before_jump;
0150     u8 rds_mode;    /* RDS operation mode (RDS/RDBS) */
0151     u8 af_mode; /* Alternate frequency on/off */
0152     struct tuned_station_info stat_info;
0153     struct fm_rds rds;
0154 };
0155 
0156 #define FMTX_RDS_TXT_STR_SIZE   25
0157 /*
0158  * FM TX RDS data
0159  *
0160  * @ text_type: is the text following PS or RT
0161  * @ text: radio text string which could either be PS or RT
0162  * @ af_freq: alternate frequency for Tx
0163  * TODO: to be declared in application
0164  */
0165 struct tx_rds {
0166     u8 text_type;
0167     u8 text[FMTX_RDS_TXT_STR_SIZE];
0168     u8 flag;
0169     u32 af_freq;
0170 };
0171 /*
0172  * FM TX global data
0173  *
0174  * @ pwr_lvl: Power Level of the Transmission from mixer control
0175  * @ xmit_state: Transmission state = Updated locally upon Start/Stop
0176  * @ audio_io: i2S/Analog
0177  * @ tx_frq: Transmission frequency
0178  */
0179 struct fmtx_data {
0180     u8 pwr_lvl;
0181     u8 xmit_state;
0182     u8 audio_io;
0183     u8 region;
0184     u16 aud_mode;
0185     u32 preemph;
0186     u32 tx_frq;
0187     struct tx_rds rds;
0188 };
0189 
0190 /* FM driver operation structure */
0191 struct fmdev {
0192     struct video_device *radio_dev; /* V4L2 video device pointer */
0193     struct v4l2_device v4l2_dev;    /* V4L2 top level struct */
0194     struct snd_card *card;  /* Card which holds FM mixer controls */
0195     u16 asci_id;
0196     spinlock_t rds_buff_lock; /* To protect access to RDS buffer */
0197     spinlock_t resp_skb_lock; /* To protect access to received SKB */
0198 
0199     long flag;      /*  FM driver state machine info */
0200     int streg_cbdata; /* status of ST registration */
0201 
0202     struct sk_buff_head rx_q;   /* RX queue */
0203     struct tasklet_struct rx_task;  /* RX Tasklet */
0204 
0205     struct sk_buff_head tx_q;   /* TX queue */
0206     struct tasklet_struct tx_task;  /* TX Tasklet */
0207     unsigned long last_tx_jiffies;  /* Timestamp of last pkt sent */
0208     atomic_t tx_cnt;    /* Number of packets can send at a time */
0209 
0210     struct sk_buff *resp_skb;   /* Response from the chip */
0211     /* Main task completion handler */
0212     struct completion maintask_comp;
0213     /* Opcode of last command sent to the chip */
0214     u8 pre_op;
0215     /* Handler used for wakeup when response packet is received */
0216     struct completion *resp_comp;
0217     struct fm_irq irq_info;
0218     u8 curr_fmmode; /* Current FM chip mode (TX, RX, OFF) */
0219     struct fm_rx rx;    /* FM receiver info */
0220     struct fmtx_data tx_data;
0221 
0222     /* V4L2 ctrl framework handler*/
0223     struct v4l2_ctrl_handler ctrl_handler;
0224 
0225     /* For core assisted locking */
0226     struct mutex mutex;
0227 };
0228 #endif