// SPDX-License-Identifier: GPL-2.0-only /* * GemTek radio card driver * * Copyright 1998 Jonas Munsin <jmunsin@iki.fi> * * GemTek hasn't released any specs on the card, so the protocol had to * be reverse engineered with dosemu. * * Besides the protocol changes, this is mostly a copy of: * * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff * * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk> * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> * * Converted to the radio-isa framework by Hans Verkuil <hansverk@cisco.com> * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org> * * Note: this card seems to swap the left and right audio channels! * * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
*/
MODULE_AUTHOR("Jonas Munsin, Pekka Seppänen <pexu@kapsi.fi>");
MODULE_DESCRIPTION("A driver for the GemTek Radio card.");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0.0");
module_param(hardmute, bool, 0644);
MODULE_PARM_DESC(hardmute, "Enable 'hard muting' by shutting down PLL, may reduce static noise.");
module_param_array(io, int, NULL, 0444);
MODULE_PARM_DESC(io, "Force I/O ports for the GemTek Radio card if automatic probing is disabled or fails. The most common I/O ports are: 0x20c 0x30c, 0x24c or 0x34c (0x20c, 0x248 and 0x28c have been reported to work for the combined sound/radiocard).");
/* * Set data which will be sent to BU2614FS.
*/ #define gemtek_bu2614_set(dev, field, data) ((dev)->bu2614data = \
((dev)->bu2614data & ~field##_MASK) | ((data) << field##_SHIFT))
/* * Transmit settings to BU2614FS over GemTek IC.
*/ staticvoid gemtek_bu2614_transmit(struct gemtek *gt)
{ struct radio_isa_card *isa = >->isa; int i, bit, q, mute;
/* * Set mute flag.
*/ staticint gemtek_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
{ struct gemtek *gt = container_of(isa, struct gemtek, isa); int i;
gt->muted = mute; if (hardmute) { if (!mute) return gemtek_s_frequency(isa, isa->freq);
/* Turn off PLL, disable data output */
gemtek_bu2614_set(gt, BU2614_PORT, 0);
gemtek_bu2614_set(gt, BU2614_FMES, 0); /* CT bit off */
gemtek_bu2614_set(gt, BU2614_SWIN, 0); /* FM-mode */
gemtek_bu2614_set(gt, BU2614_SWAL, 0);
gemtek_bu2614_set(gt, BU2614_FMUN, 0); /* GT bit off */
gemtek_bu2614_set(gt, BU2614_TEST, 0);
gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_PLL_OFF);
gemtek_bu2614_set(gt, BU2614_FREQ, 0);
gemtek_bu2614_transmit(gt); return 0;
}
/* Read bus contents (CE, CK and DA). */
i = inb_p(isa->io); /* Write it back with mute flag set. */
outb_p((i >> 5) | (mute ? GEMTEK_MT : 0), isa->io);
udelay(SHORT_DELAY); return 0;
}
/* * Check if requested card acts like GemTek Radio card.
*/ staticbool gemtek_probe(struct radio_isa_card *isa, int io)
{ int i, q;
q = inb_p(io); /* Read bus contents before probing. */ /* Try to turn on CE, CK and DA respectively and check if card responds
properly. */ for (i = 0; i < 3; ++i) {
outb_p(1 << i, io);
udelay(SHORT_DELAY);
if ((inb_p(io) & ~GEMTEK_NS) != (0x17 | (1 << (i + 5)))) returnfalse;
}
outb_p(q >> 5, io); /* Write bus contents back. */
udelay(SHORT_DELAY); returntrue;
}
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.