Lines Matching +full:crystal +full:- +full:freq

1 // SPDX-License-Identifier: GPL-2.0-or-later
14 #include <media/v4l2-device.h>
15 #include <media/v4l2-dev.h>
16 #include <media/v4l2-fh.h>
17 #include <media/v4l2-ioctl.h>
18 #include <media/v4l2-event.h>
19 #include <media/drv-intf/tea575x.h>
87 if (tea->ops->write_val) in snd_tea575x_write()
88 return tea->ops->write_val(tea, val); in snd_tea575x_write()
90 tea->ops->set_direction(tea, 1); in snd_tea575x_write()
93 for (l = 25; l > 0; l--) { in snd_tea575x_write()
96 tea->ops->set_pins(tea, data | TEA575X_WREN); in snd_tea575x_write()
98 tea->ops->set_pins(tea, data | TEA575X_WREN | TEA575X_CLK); in snd_tea575x_write()
100 tea->ops->set_pins(tea, data | TEA575X_WREN); in snd_tea575x_write()
104 if (!tea->mute) in snd_tea575x_write()
105 tea->ops->set_pins(tea, 0); in snd_tea575x_write()
113 if (tea->ops->read_val) in snd_tea575x_read()
114 return tea->ops->read_val(tea); in snd_tea575x_read()
116 tea->ops->set_direction(tea, 0); in snd_tea575x_read()
117 tea->ops->set_pins(tea, 0); in snd_tea575x_read()
120 for (l = 24; l--;) { in snd_tea575x_read()
121 tea->ops->set_pins(tea, TEA575X_CLK); in snd_tea575x_read()
124 tea->tuned = tea->ops->get_pins(tea) & TEA575X_MOST ? 0 : 1; in snd_tea575x_read()
125 tea->ops->set_pins(tea, 0); in snd_tea575x_read()
128 rdata = tea->ops->get_pins(tea); in snd_tea575x_read()
130 tea->stereo = (rdata & TEA575X_MOST) ? 0 : 1; in snd_tea575x_read()
136 if (tea->mute) in snd_tea575x_read()
137 tea->ops->set_pins(tea, TEA575X_WREN); in snd_tea575x_read()
144 u32 freq = val & TEA575X_BIT_FREQ_MASK; in snd_tea575x_val_to_freq() local
146 if (freq == 0) in snd_tea575x_val_to_freq()
147 return freq; in snd_tea575x_val_to_freq()
149 switch (tea->band) { in snd_tea575x_val_to_freq()
151 /* freq *= 12.5 */ in snd_tea575x_val_to_freq()
152 freq *= 125; in snd_tea575x_val_to_freq()
153 freq /= 10; in snd_tea575x_val_to_freq()
154 /* crystal fixup */ in snd_tea575x_val_to_freq()
155 freq -= TEA575X_FMIF; in snd_tea575x_val_to_freq()
158 /* freq *= 12.5 */ in snd_tea575x_val_to_freq()
159 freq *= 125; in snd_tea575x_val_to_freq()
160 freq /= 10; in snd_tea575x_val_to_freq()
161 /* crystal fixup */ in snd_tea575x_val_to_freq()
162 freq += TEA575X_FMIF; in snd_tea575x_val_to_freq()
165 /* crystal fixup */ in snd_tea575x_val_to_freq()
166 freq -= TEA575X_AMIF; in snd_tea575x_val_to_freq()
170 return clamp(freq * 16, bands[tea->band].rangelow, in snd_tea575x_val_to_freq()
171 bands[tea->band].rangehigh); /* from kHz */ in snd_tea575x_val_to_freq()
181 u32 freq = tea->freq / 16; /* to kHz */ in snd_tea575x_set_freq() local
184 switch (tea->band) { in snd_tea575x_set_freq()
187 /* crystal fixup */ in snd_tea575x_set_freq()
188 freq += TEA575X_FMIF; in snd_tea575x_set_freq()
189 /* freq /= 12.5 */ in snd_tea575x_set_freq()
190 freq *= 10; in snd_tea575x_set_freq()
191 freq /= 125; in snd_tea575x_set_freq()
195 /* crystal fixup */ in snd_tea575x_set_freq()
196 freq -= TEA575X_FMIF; in snd_tea575x_set_freq()
197 /* freq /= 12.5 */ in snd_tea575x_set_freq()
198 freq *= 10; in snd_tea575x_set_freq()
199 freq /= 125; in snd_tea575x_set_freq()
203 /* crystal fixup */ in snd_tea575x_set_freq()
204 freq += TEA575X_AMIF; in snd_tea575x_set_freq()
208 tea->val &= ~(TEA575X_BIT_FREQ_MASK | TEA575X_BIT_BAND_MASK); in snd_tea575x_set_freq()
209 tea->val |= band; in snd_tea575x_set_freq()
210 tea->val |= freq & TEA575X_BIT_FREQ_MASK; in snd_tea575x_set_freq()
211 snd_tea575x_write(tea, tea->val); in snd_tea575x_set_freq()
212 tea->freq = snd_tea575x_val_to_freq(tea, tea->val); in snd_tea575x_set_freq()
225 strscpy(v->driver, tea->v4l2_dev->name, sizeof(v->driver)); in vidioc_querycap()
226 strscpy(v->card, tea->card, sizeof(v->card)); in vidioc_querycap()
227 strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card)); in vidioc_querycap()
228 strscpy(v->bus_info, tea->bus_info, sizeof(v->bus_info)); in vidioc_querycap()
237 if (band->tuner != 0) in snd_tea575x_enum_freq_bands()
238 return -EINVAL; in snd_tea575x_enum_freq_bands()
240 switch (band->index) { in snd_tea575x_enum_freq_bands()
242 if (tea->tea5759) in snd_tea575x_enum_freq_bands()
248 if (tea->has_am) { in snd_tea575x_enum_freq_bands()
254 return -EINVAL; in snd_tea575x_enum_freq_bands()
258 if (!tea->cannot_read_data) in snd_tea575x_enum_freq_bands()
259 band->capability |= V4L2_TUNER_CAP_HWSEEK_BOUNDED; in snd_tea575x_enum_freq_bands()
277 if (v->index > 0) in snd_tea575x_g_tuner()
278 return -EINVAL; in snd_tea575x_g_tuner()
284 strscpy(v->name, tea->has_am ? "FM/AM" : "FM", sizeof(v->name)); in snd_tea575x_g_tuner()
285 v->type = V4L2_TUNER_RADIO; in snd_tea575x_g_tuner()
286 v->capability = band_fm.capability; in snd_tea575x_g_tuner()
287 v->rangelow = tea->has_am ? bands[BAND_AM].rangelow : band_fm.rangelow; in snd_tea575x_g_tuner()
288 v->rangehigh = band_fm.rangehigh; in snd_tea575x_g_tuner()
289 v->rxsubchans = tea->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; in snd_tea575x_g_tuner()
290 v->audmode = (tea->val & TEA575X_BIT_MONO) ? in snd_tea575x_g_tuner()
292 v->signal = tea->tuned ? 0xffff : 0; in snd_tea575x_g_tuner()
309 u32 orig_val = tea->val; in vidioc_s_tuner()
311 if (v->index) in vidioc_s_tuner()
312 return -EINVAL; in vidioc_s_tuner()
313 tea->val &= ~TEA575X_BIT_MONO; in vidioc_s_tuner()
314 if (v->audmode == V4L2_TUNER_MODE_MONO) in vidioc_s_tuner()
315 tea->val |= TEA575X_BIT_MONO; in vidioc_s_tuner()
317 if (tea->band != BAND_AM && tea->val != orig_val) in vidioc_s_tuner()
328 if (f->tuner != 0) in vidioc_g_frequency()
329 return -EINVAL; in vidioc_g_frequency()
330 f->type = V4L2_TUNER_RADIO; in vidioc_g_frequency()
331 f->frequency = tea->freq; in vidioc_g_frequency()
340 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) in vidioc_s_frequency()
341 return -EINVAL; in vidioc_s_frequency()
343 if (tea->has_am && f->frequency < (20000 * 16)) in vidioc_s_frequency()
344 tea->band = BAND_AM; in vidioc_s_frequency()
345 else if (tea->tea5759) in vidioc_s_frequency()
346 tea->band = BAND_FM_JAPAN; in vidioc_s_frequency()
348 tea->band = BAND_FM; in vidioc_s_frequency()
350 tea->freq = clamp_t(u32, f->frequency, bands[tea->band].rangelow, in vidioc_s_frequency()
351 bands[tea->band].rangehigh); in vidioc_s_frequency()
362 if (tea->cannot_read_data) in snd_tea575x_s_hw_freq_seek()
363 return -ENOTTY; in snd_tea575x_s_hw_freq_seek()
364 if (a->tuner || a->wrap_around) in snd_tea575x_s_hw_freq_seek()
365 return -EINVAL; in snd_tea575x_s_hw_freq_seek()
367 if (file->f_flags & O_NONBLOCK) in snd_tea575x_s_hw_freq_seek()
368 return -EWOULDBLOCK; in snd_tea575x_s_hw_freq_seek()
370 if (a->rangelow || a->rangehigh) { in snd_tea575x_s_hw_freq_seek()
372 if ((i == BAND_FM && tea->tea5759) || in snd_tea575x_s_hw_freq_seek()
373 (i == BAND_FM_JAPAN && !tea->tea5759) || in snd_tea575x_s_hw_freq_seek()
374 (i == BAND_AM && !tea->has_am)) in snd_tea575x_s_hw_freq_seek()
376 if (bands[i].rangelow == a->rangelow && in snd_tea575x_s_hw_freq_seek()
377 bands[i].rangehigh == a->rangehigh) in snd_tea575x_s_hw_freq_seek()
381 return -EINVAL; /* No matching band found */ in snd_tea575x_s_hw_freq_seek()
382 if (i != tea->band) { in snd_tea575x_s_hw_freq_seek()
383 tea->band = i; in snd_tea575x_s_hw_freq_seek()
384 tea->freq = clamp(tea->freq, bands[i].rangelow, in snd_tea575x_s_hw_freq_seek()
390 spacing = (tea->band == BAND_AM) ? 5 : 50; /* kHz */ in snd_tea575x_s_hw_freq_seek()
393 tea->val &= ~TEA575X_BIT_FREQ_MASK; in snd_tea575x_s_hw_freq_seek()
394 tea->val |= TEA575X_BIT_SEARCH; in snd_tea575x_s_hw_freq_seek()
395 if (a->seek_upward) in snd_tea575x_s_hw_freq_seek()
396 tea->val |= TEA575X_BIT_UPDOWN; in snd_tea575x_s_hw_freq_seek()
398 tea->val &= ~TEA575X_BIT_UPDOWN; in snd_tea575x_s_hw_freq_seek()
399 snd_tea575x_write(tea, tea->val); in snd_tea575x_s_hw_freq_seek()
406 tea->val &= ~TEA575X_BIT_SEARCH; in snd_tea575x_s_hw_freq_seek()
408 return -ERESTARTSYS; in snd_tea575x_s_hw_freq_seek()
411 u32 freq; in snd_tea575x_s_hw_freq_seek() local
416 freq = snd_tea575x_get_freq(tea); in snd_tea575x_s_hw_freq_seek()
417 if (freq) /* available */ in snd_tea575x_s_hw_freq_seek()
420 if (freq == 0) /* shouldn't happen */ in snd_tea575x_s_hw_freq_seek()
426 if (abs(tea->freq - freq) < 16 * spacing || in snd_tea575x_s_hw_freq_seek()
427 (a->seek_upward && freq < tea->freq) || in snd_tea575x_s_hw_freq_seek()
428 (!a->seek_upward && freq > tea->freq)) { in snd_tea575x_s_hw_freq_seek()
429 snd_tea575x_write(tea, tea->val); in snd_tea575x_s_hw_freq_seek()
432 tea->freq = freq; in snd_tea575x_s_hw_freq_seek()
433 tea->val &= ~TEA575X_BIT_SEARCH; in snd_tea575x_s_hw_freq_seek()
437 tea->val &= ~TEA575X_BIT_SEARCH; in snd_tea575x_s_hw_freq_seek()
439 return -ENODATA; in snd_tea575x_s_hw_freq_seek()
453 struct snd_tea575x *tea = container_of(ctrl->handler, struct snd_tea575x, ctrl_handler); in tea575x_s_ctrl()
455 switch (ctrl->id) { in tea575x_s_ctrl()
457 tea->mute = ctrl->val; in tea575x_s_ctrl()
462 return -EINVAL; in tea575x_s_ctrl()
497 tea->mute = true; in snd_tea575x_hw_init()
501 if (!tea->cannot_read_data) { in snd_tea575x_hw_init()
504 return -ENODEV; in snd_tea575x_hw_init()
507 tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_5_28; in snd_tea575x_hw_init()
508 tea->freq = 90500 * 16; /* 90.5Mhz default */ in snd_tea575x_hw_init()
522 tea->vd = tea575x_radio; in snd_tea575x_init()
523 video_set_drvdata(&tea->vd, tea); in snd_tea575x_init()
524 mutex_init(&tea->mutex); in snd_tea575x_init()
525 strscpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name)); in snd_tea575x_init()
526 tea->vd.lock = &tea->mutex; in snd_tea575x_init()
527 tea->vd.v4l2_dev = tea->v4l2_dev; in snd_tea575x_init()
528 tea->vd.device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO; in snd_tea575x_init()
529 if (!tea->cannot_read_data) in snd_tea575x_init()
530 tea->vd.device_caps |= V4L2_CAP_HW_FREQ_SEEK; in snd_tea575x_init()
531 tea->fops = tea575x_fops; in snd_tea575x_init()
532 tea->fops.owner = owner; in snd_tea575x_init()
533 tea->vd.fops = &tea->fops; in snd_tea575x_init()
535 if (tea->cannot_read_data) in snd_tea575x_init()
536 v4l2_disable_ioctl(&tea->vd, VIDIOC_S_HW_FREQ_SEEK); in snd_tea575x_init()
538 if (!tea->cannot_mute) { in snd_tea575x_init()
539 tea->vd.ctrl_handler = &tea->ctrl_handler; in snd_tea575x_init()
540 v4l2_ctrl_handler_init(&tea->ctrl_handler, 1); in snd_tea575x_init()
541 v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, in snd_tea575x_init()
543 retval = tea->ctrl_handler.error; in snd_tea575x_init()
545 v4l2_err(tea->v4l2_dev, "can't initialize controls\n"); in snd_tea575x_init()
546 v4l2_ctrl_handler_free(&tea->ctrl_handler); in snd_tea575x_init()
550 if (tea->ext_init) { in snd_tea575x_init()
551 retval = tea->ext_init(tea); in snd_tea575x_init()
553 v4l2_ctrl_handler_free(&tea->ctrl_handler); in snd_tea575x_init()
558 v4l2_ctrl_handler_setup(&tea->ctrl_handler); in snd_tea575x_init()
561 retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->radio_nr); in snd_tea575x_init()
563 v4l2_err(tea->v4l2_dev, "can't register video device!\n"); in snd_tea575x_init()
564 v4l2_ctrl_handler_free(tea->vd.ctrl_handler); in snd_tea575x_init()
574 video_unregister_device(&tea->vd); in snd_tea575x_exit()
575 v4l2_ctrl_handler_free(tea->vd.ctrl_handler); in snd_tea575x_exit()