Lines Matching +full:high +full:- +full:vt
1 // SPDX-License-Identifier: GPL-2.0-only
3 * vivid-radio-rx.c - radio receiver support functions.
12 #include <linux/v4l2-dv-timings.h>
15 #include <media/v4l2-common.h>
16 #include <media/v4l2-event.h>
17 #include <media/v4l2-dv-timings.h>
19 #include "vivid-core.h"
20 #include "vivid-ctrls.h"
21 #include "vivid-radio-common.h"
22 #include "vivid-rds-gen.h"
23 #include "vivid-radio-rx.h"
29 struct v4l2_rds_data *data = dev->rds_gen.data; in vivid_radio_rx_read()
36 if (dev->radio_rx_rds_controls) in vivid_radio_rx_read()
37 return -EINVAL; in vivid_radio_rx_read()
42 if (mutex_lock_interruptible(&dev->mutex)) in vivid_radio_rx_read()
43 return -ERESTARTSYS; in vivid_radio_rx_read()
44 if (dev->radio_rx_rds_owner && in vivid_radio_rx_read()
45 file->private_data != dev->radio_rx_rds_owner) { in vivid_radio_rx_read()
46 mutex_unlock(&dev->mutex); in vivid_radio_rx_read()
47 return -EBUSY; in vivid_radio_rx_read()
49 if (dev->radio_rx_rds_owner == NULL) { in vivid_radio_rx_read()
51 dev->radio_rx_rds_owner = file->private_data; in vivid_radio_rx_read()
55 timestamp = ktime_sub(ktime_get(), dev->radio_rds_init_time); in vivid_radio_rx_read()
59 if (dev->radio_rx_rds_last_block == 0 || in vivid_radio_rx_read()
60 dev->radio_rx_rds_use_alternates != use_alternates) { in vivid_radio_rx_read()
61 dev->radio_rx_rds_use_alternates = use_alternates; in vivid_radio_rx_read()
62 /* Re-init the RDS generator */ in vivid_radio_rx_read()
65 if (blk >= dev->radio_rx_rds_last_block + VIVID_RDS_GEN_BLOCKS) in vivid_radio_rx_read()
66 dev->radio_rx_rds_last_block = blk - VIVID_RDS_GEN_BLOCKS + 1; in vivid_radio_rx_read()
74 if (blk == dev->radio_rx_rds_last_block || !dev->radio_rx_rds_enabled || in vivid_radio_rx_read()
75 (dev->radio_rds_loop && !(dev->radio_tx_subchans & V4L2_TUNER_SUB_RDS)) || in vivid_radio_rx_read()
76 abs(dev->radio_rx_sig_qual) > 200) { in vivid_radio_rx_read()
77 mutex_unlock(&dev->mutex); in vivid_radio_rx_read()
78 if (file->f_flags & O_NONBLOCK) in vivid_radio_rx_read()
79 return -EWOULDBLOCK; in vivid_radio_rx_read()
81 return -EINTR; in vivid_radio_rx_read()
82 if (mutex_lock_interruptible(&dev->mutex)) in vivid_radio_rx_read()
83 return -ERESTARTSYS; in vivid_radio_rx_read()
87 /* abs(dev->radio_rx_sig_qual) <= 200, map that to a 0-50% range */ in vivid_radio_rx_read()
88 perc = abs(dev->radio_rx_sig_qual) / 4; in vivid_radio_rx_read()
90 for (i = 0; i < size && blk > dev->radio_rx_rds_last_block; in vivid_radio_rx_read()
91 dev->radio_rx_rds_last_block++) { in vivid_radio_rx_read()
92 unsigned data_blk = dev->radio_rx_rds_last_block % VIVID_RDS_GEN_BLOCKS; in vivid_radio_rx_read()
95 if (data_blk == 0 && dev->radio_rds_loop) in vivid_radio_rx_read()
116 * might think that end-of-file occurred. in vivid_radio_rx_read()
122 i = -EFAULT; in vivid_radio_rx_read()
127 mutex_unlock(&dev->mutex); in vivid_radio_rx_read()
138 if (band->tuner != 0) in vivid_radio_rx_enum_freq_bands()
139 return -EINVAL; in vivid_radio_rx_enum_freq_bands()
141 if (band->index >= TOT_BANDS) in vivid_radio_rx_enum_freq_bands()
142 return -EINVAL; in vivid_radio_rx_enum_freq_bands()
144 *band = vivid_radio_bands[band->index]; in vivid_radio_rx_enum_freq_bands()
151 unsigned low, high; in vivid_radio_rx_s_hw_freq_seek() local
156 if (a->tuner) in vivid_radio_rx_s_hw_freq_seek()
157 return -EINVAL; in vivid_radio_rx_s_hw_freq_seek()
158 if (a->wrap_around && dev->radio_rx_hw_seek_mode == VIVID_HW_SEEK_BOUNDED) in vivid_radio_rx_s_hw_freq_seek()
159 return -EINVAL; in vivid_radio_rx_s_hw_freq_seek()
161 if (!a->wrap_around && dev->radio_rx_hw_seek_mode == VIVID_HW_SEEK_WRAP) in vivid_radio_rx_s_hw_freq_seek()
162 return -EINVAL; in vivid_radio_rx_s_hw_freq_seek()
163 if (!a->rangelow ^ !a->rangehigh) in vivid_radio_rx_s_hw_freq_seek()
164 return -EINVAL; in vivid_radio_rx_s_hw_freq_seek()
166 if (file->f_flags & O_NONBLOCK) in vivid_radio_rx_s_hw_freq_seek()
167 return -EWOULDBLOCK; in vivid_radio_rx_s_hw_freq_seek()
169 if (a->rangelow) { in vivid_radio_rx_s_hw_freq_seek()
171 if (a->rangelow >= vivid_radio_bands[band].rangelow && in vivid_radio_rx_s_hw_freq_seek()
172 a->rangehigh <= vivid_radio_bands[band].rangehigh) in vivid_radio_rx_s_hw_freq_seek()
175 return -EINVAL; in vivid_radio_rx_s_hw_freq_seek()
176 if (!dev->radio_rx_hw_seek_prog_lim && in vivid_radio_rx_s_hw_freq_seek()
177 (a->rangelow != vivid_radio_bands[band].rangelow || in vivid_radio_rx_s_hw_freq_seek()
178 a->rangehigh != vivid_radio_bands[band].rangehigh)) in vivid_radio_rx_s_hw_freq_seek()
179 return -EINVAL; in vivid_radio_rx_s_hw_freq_seek()
180 low = a->rangelow; in vivid_radio_rx_s_hw_freq_seek()
181 high = a->rangehigh; in vivid_radio_rx_s_hw_freq_seek()
184 if (dev->radio_rx_freq >= vivid_radio_bands[band].rangelow && in vivid_radio_rx_s_hw_freq_seek()
185 dev->radio_rx_freq <= vivid_radio_bands[band].rangehigh) in vivid_radio_rx_s_hw_freq_seek()
188 return -EINVAL; in vivid_radio_rx_s_hw_freq_seek()
190 high = vivid_radio_bands[band].rangehigh; in vivid_radio_rx_s_hw_freq_seek()
193 freq = clamp(dev->radio_rx_freq, low, high); in vivid_radio_rx_s_hw_freq_seek()
195 if (a->seek_upward) { in vivid_radio_rx_s_hw_freq_seek()
197 if (freq > high) { in vivid_radio_rx_s_hw_freq_seek()
198 if (!a->wrap_around) in vivid_radio_rx_s_hw_freq_seek()
199 return -ENODATA; in vivid_radio_rx_s_hw_freq_seek()
201 if (freq >= dev->radio_rx_freq) in vivid_radio_rx_s_hw_freq_seek()
202 return -ENODATA; in vivid_radio_rx_s_hw_freq_seek()
205 freq = spacing * ((freq + spacing - 1) / spacing) - spacing; in vivid_radio_rx_s_hw_freq_seek()
207 if (!a->wrap_around) in vivid_radio_rx_s_hw_freq_seek()
208 return -ENODATA; in vivid_radio_rx_s_hw_freq_seek()
209 freq = spacing * ((high + spacing - 1) / spacing) - spacing; in vivid_radio_rx_s_hw_freq_seek()
210 if (freq <= dev->radio_rx_freq) in vivid_radio_rx_s_hw_freq_seek()
211 return -ENODATA; in vivid_radio_rx_s_hw_freq_seek()
217 int vivid_radio_rx_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) in vivid_radio_rx_g_tuner() argument
223 if (vt->index > 0) in vivid_radio_rx_g_tuner()
224 return -EINVAL; in vivid_radio_rx_g_tuner()
226 strscpy(vt->name, "AM/FM/SW Receiver", sizeof(vt->name)); in vivid_radio_rx_g_tuner()
227 vt->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | in vivid_radio_rx_g_tuner()
229 (dev->radio_rx_rds_controls ? in vivid_radio_rx_g_tuner()
232 (dev->radio_rx_hw_seek_prog_lim ? in vivid_radio_rx_g_tuner()
234 switch (dev->radio_rx_hw_seek_mode) { in vivid_radio_rx_g_tuner()
236 vt->capability |= V4L2_TUNER_CAP_HWSEEK_BOUNDED; in vivid_radio_rx_g_tuner()
239 vt->capability |= V4L2_TUNER_CAP_HWSEEK_WRAP; in vivid_radio_rx_g_tuner()
242 vt->capability |= V4L2_TUNER_CAP_HWSEEK_WRAP | in vivid_radio_rx_g_tuner()
246 vt->rangelow = AM_FREQ_RANGE_LOW; in vivid_radio_rx_g_tuner()
247 vt->rangehigh = FM_FREQ_RANGE_HIGH; in vivid_radio_rx_g_tuner()
248 sig_qual = dev->radio_rx_sig_qual; in vivid_radio_rx_g_tuner()
249 vt->signal = abs(sig_qual) > delta ? 0 : in vivid_radio_rx_g_tuner()
250 0xffff - ((unsigned)abs(sig_qual) * 0xffff) / delta; in vivid_radio_rx_g_tuner()
251 vt->afc = sig_qual > delta ? 0 : sig_qual; in vivid_radio_rx_g_tuner()
253 vt->rxsubchans = 0; in vivid_radio_rx_g_tuner()
254 else if (dev->radio_rx_freq < FM_FREQ_RANGE_LOW || vt->signal < 0x8000) in vivid_radio_rx_g_tuner()
255 vt->rxsubchans = V4L2_TUNER_SUB_MONO; in vivid_radio_rx_g_tuner()
256 else if (dev->radio_rds_loop && !(dev->radio_tx_subchans & V4L2_TUNER_SUB_STEREO)) in vivid_radio_rx_g_tuner()
257 vt->rxsubchans = V4L2_TUNER_SUB_MONO; in vivid_radio_rx_g_tuner()
259 vt->rxsubchans = V4L2_TUNER_SUB_STEREO; in vivid_radio_rx_g_tuner()
260 if (dev->radio_rx_rds_enabled && in vivid_radio_rx_g_tuner()
261 (!dev->radio_rds_loop || (dev->radio_tx_subchans & V4L2_TUNER_SUB_RDS)) && in vivid_radio_rx_g_tuner()
262 dev->radio_rx_freq >= FM_FREQ_RANGE_LOW && vt->signal >= 0xc000) in vivid_radio_rx_g_tuner()
263 vt->rxsubchans |= V4L2_TUNER_SUB_RDS; in vivid_radio_rx_g_tuner()
264 if (dev->radio_rx_rds_controls) in vivid_radio_rx_g_tuner()
266 vt->audmode = dev->radio_rx_audmode; in vivid_radio_rx_g_tuner()
270 int vivid_radio_rx_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt) in vivid_radio_rx_s_tuner() argument
274 if (vt->index) in vivid_radio_rx_s_tuner()
275 return -EINVAL; in vivid_radio_rx_s_tuner()
276 dev->radio_rx_audmode = vt->audmode >= V4L2_TUNER_MODE_STEREO; in vivid_radio_rx_s_tuner()