1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * FM Driver for Connectivity chip of Texas Instruments. |
4 | * |
5 | * Common header for all FM driver sub-modules. |
6 | * |
7 | * Copyright (C) 2011 Texas Instruments |
8 | */ |
9 | |
10 | #ifndef _FM_DRV_H |
11 | #define _FM_DRV_H |
12 | |
13 | #include <linux/skbuff.h> |
14 | #include <linux/interrupt.h> |
15 | #include <sound/core.h> |
16 | #include <sound/initval.h> |
17 | #include <linux/timer.h> |
18 | #include <media/v4l2-ioctl.h> |
19 | #include <media/v4l2-common.h> |
20 | #include <media/v4l2-device.h> |
21 | #include <media/v4l2-ctrls.h> |
22 | |
23 | #define FM_DRV_VERSION "0.1.1" |
24 | #define FM_DRV_NAME "ti_fmdrv" |
25 | #define FM_DRV_CARD_SHORT_NAME "TI FM Radio" |
26 | #define FM_DRV_CARD_LONG_NAME "Texas Instruments FM Radio" |
27 | |
28 | /* Flag info */ |
29 | #define FM_INTTASK_RUNNING 0 |
30 | #define FM_INTTASK_SCHEDULE_PENDING 1 |
31 | #define FM_FW_DW_INPROGRESS 2 |
32 | #define FM_CORE_READY 3 |
33 | #define FM_CORE_TRANSPORT_READY 4 |
34 | #define FM_AF_SWITCH_INPROGRESS 5 |
35 | #define FM_CORE_TX_XMITING 6 |
36 | |
37 | #define FM_TUNE_COMPLETE 0x1 |
38 | #define FM_BAND_LIMIT 0x2 |
39 | |
40 | #define FM_DRV_TX_TIMEOUT (5*HZ) /* 5 seconds */ |
41 | #define FM_DRV_RX_SEEK_TIMEOUT (20*HZ) /* 20 seconds */ |
42 | |
43 | #define fmerr(format, ...) \ |
44 | printk(KERN_ERR "fmdrv: " format, ## __VA_ARGS__) |
45 | #define fmwarn(format, ...) \ |
46 | printk(KERN_WARNING "fmdrv: " format, ##__VA_ARGS__) |
47 | #ifdef DEBUG |
48 | #define fmdbg(format, ...) \ |
49 | printk(KERN_DEBUG "fmdrv: " format, ## __VA_ARGS__) |
50 | #else /* DEBUG */ |
51 | #define fmdbg(format, ...) do {} while(0) |
52 | #endif |
53 | enum { |
54 | FM_MODE_OFF, |
55 | FM_MODE_TX, |
56 | FM_MODE_RX, |
57 | FM_MODE_ENTRY_MAX |
58 | }; |
59 | |
60 | #define FM_RX_RDS_INFO_FIELD_MAX 8 /* 4 Group * 2 Bytes */ |
61 | |
62 | /* RX RDS data format */ |
63 | struct fm_rdsdata_format { |
64 | union { |
65 | struct { |
66 | u8 buff[FM_RX_RDS_INFO_FIELD_MAX]; |
67 | } groupdatabuff; |
68 | struct { |
69 | u16 pidata; |
70 | u8 blk_b[2]; |
71 | u8 blk_c[2]; |
72 | u8 blk_d[2]; |
73 | } groupgeneral; |
74 | struct { |
75 | u16 pidata; |
76 | u8 blk_b[2]; |
77 | u8 af[2]; |
78 | u8 ps[2]; |
79 | } group0A; |
80 | struct { |
81 | u16 pi[2]; |
82 | u8 blk_b[2]; |
83 | u8 ps[2]; |
84 | } group0B; |
85 | } data; |
86 | }; |
87 | |
88 | /* FM region (Europe/US, Japan) info */ |
89 | struct region_info { |
90 | u32 chanl_space; |
91 | u32 bot_freq; |
92 | u32 top_freq; |
93 | u8 fm_band; |
94 | }; |
95 | struct fmdev; |
96 | typedef void (*int_handler_prototype) (struct fmdev *); |
97 | |
98 | /* FM Interrupt processing related info */ |
99 | struct fm_irq { |
100 | u8 stage; |
101 | u16 flag; /* FM interrupt flag */ |
102 | u16 mask; /* FM interrupt mask */ |
103 | /* Interrupt process timeout handler */ |
104 | struct timer_list timer; |
105 | u8 retry; |
106 | int_handler_prototype *handlers; |
107 | }; |
108 | |
109 | /* RDS info */ |
110 | struct fm_rds { |
111 | u8 flag; /* RX RDS on/off status */ |
112 | u8 last_blk_idx; /* Last received RDS block */ |
113 | |
114 | /* RDS buffer */ |
115 | wait_queue_head_t read_queue; |
116 | u32 buf_size; /* Size is always multiple of 3 */ |
117 | u32 wr_idx; |
118 | u32 rd_idx; |
119 | u8 *buff; |
120 | }; |
121 | |
122 | #define FM_RDS_MAX_AF_LIST 25 |
123 | |
124 | /* |
125 | * Current RX channel Alternate Frequency cache. |
126 | * This info is used to switch to other freq (AF) |
127 | * when current channel signal strength is below RSSI threshold. |
128 | */ |
129 | struct tuned_station_info { |
130 | u16 picode; |
131 | u32 af_cache[FM_RDS_MAX_AF_LIST]; |
132 | u8 afcache_size; |
133 | u8 af_list_max; |
134 | }; |
135 | |
136 | /* FM RX mode info */ |
137 | struct fm_rx { |
138 | struct region_info region; /* Current selected band */ |
139 | u32 freq; /* Current RX frquency */ |
140 | u8 mute_mode; /* Current mute mode */ |
141 | u8 deemphasis_mode; /* Current deemphasis mode */ |
142 | /* RF dependent soft mute mode */ |
143 | u8 rf_depend_mute; |
144 | u16 volume; /* Current volume level */ |
145 | u16 ; /* Current RSSI threshold level */ |
146 | /* Holds the index of the current AF jump */ |
147 | u8 afjump_idx; |
148 | /* Will hold the frequency before the jump */ |
149 | u32 freq_before_jump; |
150 | u8 rds_mode; /* RDS operation mode (RDS/RDBS) */ |
151 | u8 af_mode; /* Alternate frequency on/off */ |
152 | struct tuned_station_info stat_info; |
153 | struct fm_rds rds; |
154 | }; |
155 | |
156 | #define FMTX_RDS_TXT_STR_SIZE 25 |
157 | /* |
158 | * FM TX RDS data |
159 | * |
160 | * @ text_type: is the text following PS or RT |
161 | * @ text: radio text string which could either be PS or RT |
162 | * @ af_freq: alternate frequency for Tx |
163 | * TODO: to be declared in application |
164 | */ |
165 | struct tx_rds { |
166 | u8 text_type; |
167 | u8 text[FMTX_RDS_TXT_STR_SIZE]; |
168 | u8 flag; |
169 | u32 af_freq; |
170 | }; |
171 | /* |
172 | * FM TX global data |
173 | * |
174 | * @ pwr_lvl: Power Level of the Transmission from mixer control |
175 | * @ xmit_state: Transmission state = Updated locally upon Start/Stop |
176 | * @ audio_io: i2S/Analog |
177 | * @ tx_frq: Transmission frequency |
178 | */ |
179 | struct fmtx_data { |
180 | u8 pwr_lvl; |
181 | u8 xmit_state; |
182 | u8 audio_io; |
183 | u8 region; |
184 | u16 aud_mode; |
185 | u32 preemph; |
186 | u32 tx_frq; |
187 | struct tx_rds rds; |
188 | }; |
189 | |
190 | /* FM driver operation structure */ |
191 | struct fmdev { |
192 | struct video_device *radio_dev; /* V4L2 video device pointer */ |
193 | struct v4l2_device v4l2_dev; /* V4L2 top level struct */ |
194 | struct snd_card *card; /* Card which holds FM mixer controls */ |
195 | u16 asci_id; |
196 | spinlock_t rds_buff_lock; /* To protect access to RDS buffer */ |
197 | spinlock_t resp_skb_lock; /* To protect access to received SKB */ |
198 | |
199 | long flag; /* FM driver state machine info */ |
200 | int streg_cbdata; /* status of ST registration */ |
201 | |
202 | struct sk_buff_head rx_q; /* RX queue */ |
203 | struct tasklet_struct rx_task; /* RX Tasklet */ |
204 | |
205 | struct sk_buff_head tx_q; /* TX queue */ |
206 | struct tasklet_struct tx_task; /* TX Tasklet */ |
207 | unsigned long last_tx_jiffies; /* Timestamp of last pkt sent */ |
208 | atomic_t tx_cnt; /* Number of packets can send at a time */ |
209 | |
210 | struct sk_buff *resp_skb; /* Response from the chip */ |
211 | /* Main task completion handler */ |
212 | struct completion maintask_comp; |
213 | /* Opcode of last command sent to the chip */ |
214 | u8 pre_op; |
215 | /* Handler used for wakeup when response packet is received */ |
216 | struct completion *resp_comp; |
217 | struct fm_irq irq_info; |
218 | u8 curr_fmmode; /* Current FM chip mode (TX, RX, OFF) */ |
219 | struct fm_rx rx; /* FM receiver info */ |
220 | struct fmtx_data tx_data; |
221 | |
222 | /* V4L2 ctrl framework handler*/ |
223 | struct v4l2_ctrl_handler ctrl_handler; |
224 | |
225 | /* For core assisted locking */ |
226 | struct mutex mutex; |
227 | }; |
228 | #endif |
229 | |