MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips");
MODULE_LICENSE("GPL");
/* * definitions
*/
#define TEA575X_BIT_SEARCH (1<<24) /* 1 = search action, 0 = tuned */ #define TEA575X_BIT_UPDOWN (1<<23) /* 0 = search down, 1 = search up */ #define TEA575X_BIT_MONO (1<<22) /* 0 = stereo, 1 = mono */ #define TEA575X_BIT_BAND_MASK (3<<20) #define TEA575X_BIT_BAND_FM (0<<20) #define TEA575X_BIT_BAND_MW (1<<20) #define TEA575X_BIT_BAND_LW (2<<20) #define TEA575X_BIT_BAND_SW (3<<20) #define TEA575X_BIT_PORT_0 (1<<19) /* user bit */ #define TEA575X_BIT_PORT_1 (1<<18) /* user bit */ #define TEA575X_BIT_SEARCH_MASK (3<<16) /* search level */ #define TEA575X_BIT_SEARCH_5_28 (0<<16) /* FM >5uV, AM >28uV */ #define TEA575X_BIT_SEARCH_10_40 (1<<16) /* FM >10uV, AM > 40uV */ #define TEA575X_BIT_SEARCH_30_63 (2<<16) /* FM >30uV, AM > 63uV */ #define TEA575X_BIT_SEARCH_150_1000 (3<<16) /* FM > 150uV, AM > 1000uV */ #define TEA575X_BIT_DUMMY (1<<15) /* buffer */ #define TEA575X_BIT_FREQ_MASK 0x7fff
int snd_tea575x_enum_freq_bands(struct snd_tea575x *tea, struct v4l2_frequency_band *band)
{ int index;
if (band->tuner != 0) return -EINVAL;
switch (band->index) { case 0: if (tea->tea5759)
index = BAND_FM_JAPAN; else
index = BAND_FM; break; case 1: if (tea->has_am) {
index = BAND_AM; break;
}
fallthrough; default: return -EINVAL;
}
*band = bands[index]; if (!tea->cannot_read_data)
band->capability |= V4L2_TUNER_CAP_HWSEEK_BOUNDED;
if (v->index) return -EINVAL;
tea->val &= ~TEA575X_BIT_MONO; if (v->audmode == V4L2_TUNER_MODE_MONO)
tea->val |= TEA575X_BIT_MONO; /* Only apply changes if currently tuning FM */ if (tea->band != BAND_AM && tea->val != orig_val)
snd_tea575x_set_freq(tea);
int snd_tea575x_s_hw_freq_seek(struct file *file, struct snd_tea575x *tea, conststruct v4l2_hw_freq_seek *a)
{ unsignedlong timeout; int i, spacing;
if (tea->cannot_read_data) return -ENOTTY; if (a->tuner || a->wrap_around) return -EINVAL;
if (file->f_flags & O_NONBLOCK) return -EWOULDBLOCK;
if (a->rangelow || a->rangehigh) { for (i = 0; i < ARRAY_SIZE(bands); i++) { if ((i == BAND_FM && tea->tea5759) ||
(i == BAND_FM_JAPAN && !tea->tea5759) ||
(i == BAND_AM && !tea->has_am)) continue; if (bands[i].rangelow == a->rangelow &&
bands[i].rangehigh == a->rangehigh) break;
} if (i == ARRAY_SIZE(bands)) return -EINVAL; /* No matching band found */ if (i != tea->band) {
tea->band = i;
tea->freq = clamp(tea->freq, bands[i].rangelow,
bands[i].rangehigh);
snd_tea575x_set_freq(tea);
}
}
/* clear the frequency, HW will fill it in */
tea->val &= ~TEA575X_BIT_FREQ_MASK;
tea->val |= TEA575X_BIT_SEARCH; if (a->seek_upward)
tea->val |= TEA575X_BIT_UPDOWN; else
tea->val &= ~TEA575X_BIT_UPDOWN;
snd_tea575x_write(tea, tea->val);
timeout = jiffies + msecs_to_jiffies(10000); for (;;) { if (time_after(jiffies, timeout)) break; if (schedule_timeout_interruptible(msecs_to_jiffies(10))) { /* some signal arrived, stop search */
tea->val &= ~TEA575X_BIT_SEARCH;
snd_tea575x_set_freq(tea); return -ERESTARTSYS;
} if (!(snd_tea575x_read(tea) & TEA575X_BIT_SEARCH)) {
u32 freq;
/* Found a frequency, wait until it can be read */ for (i = 0; i < 100; i++) {
msleep(10);
freq = snd_tea575x_get_freq(tea); if (freq) /* available */ break;
} if (freq == 0) /* shouldn't happen */ break; /* * if we moved by less than the spacing, or in the * wrong direction, continue seeking
*/ if (abs(tea->freq - freq) < 16 * spacing ||
(a->seek_upward && freq < tea->freq) ||
(!a->seek_upward && freq > tea->freq)) {
snd_tea575x_write(tea, tea->val); continue;
}
tea->freq = freq;
tea->val &= ~TEA575X_BIT_SEARCH; return 0;
}
}
tea->val &= ~TEA575X_BIT_SEARCH;
snd_tea575x_set_freq(tea); return -ENODATA;
}
EXPORT_SYMBOL(snd_tea575x_s_hw_freq_seek);
int snd_tea575x_hw_init(struct snd_tea575x *tea)
{
tea->mute = true;
/* Not all devices can or know how to read the data back.
Such devices can set cannot_read_data to true. */ if (!tea->cannot_read_data) {
snd_tea575x_write(tea, 0x55AA); if (snd_tea575x_read(tea) != 0x55AA) return -ENODEV;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.