1/* GemTek radio card driver for Linux (C) 1998 Jonas Munsin <jmunsin@iki.fi> 2 * 3 * GemTek hasn't released any specs on the card, so the protocol had to 4 * be reverse engineered with dosemu. 5 * 6 * Besides the protocol changes, this is mostly a copy of: 7 * 8 * RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff 9 * 10 * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood 11 * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk> 12 * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> 13 * 14 * TODO: Allow for more than one of these foolish entities :-) 15 * 16 * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> 17 */ 18 19#include <linux/module.h> /* Modules */ 20#include <linux/init.h> /* Initdata */ 21#include <linux/ioport.h> /* request_region */ 22#include <linux/delay.h> /* udelay */ 23#include <linux/videodev2.h> /* kernel radio structs */ 24#include <linux/version.h> /* for KERNEL_VERSION MACRO */ 25#include <linux/mutex.h> 26#include <linux/io.h> /* outb, outb_p */ 27#include <media/v4l2-ioctl.h> 28#include <media/v4l2-device.h> 29 30#define RADIO_VERSION KERNEL_VERSION(0, 0, 3) 31 32/* 33 * Module info. 34 */ 35 36MODULE_AUTHOR("Jonas Munsin, Pekka Sepp�nen <pexu@kapsi.fi>"); 37MODULE_DESCRIPTION("A driver for the GemTek Radio card."); 38MODULE_LICENSE("GPL"); 39 40/* 41 * Module params. 42 */ 43 44#ifndef CONFIG_RADIO_GEMTEK_PORT 45#define CONFIG_RADIO_GEMTEK_PORT -1 46#endif 47#ifndef CONFIG_RADIO_GEMTEK_PROBE 48#define CONFIG_RADIO_GEMTEK_PROBE 1 49#endif 50 51static int io = CONFIG_RADIO_GEMTEK_PORT; 52static int probe = CONFIG_RADIO_GEMTEK_PROBE; 53static int hardmute; 54static int shutdown = 1; 55static int keepmuted = 1; 56static int initmute = 1; 57static int radio_nr = -1; 58 59module_param(io, int, 0444); 60MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic " 61 "probing is disabled or fails. The most common I/O ports are: 0x20c " 62 "0x30c, 0x24c or 0x34c (0x20c, 0x248 and 0x28c have been reported to " 63 "work for the combined sound/radiocard)."); 64 65module_param(probe, bool, 0444); 66MODULE_PARM_DESC(probe, "Enable automatic device probing. Note: only the most " 67 "common I/O ports used by the card are probed."); 68 69module_param(hardmute, bool, 0644); 70MODULE_PARM_DESC(hardmute, "Enable `hard muting' by shutting down PLL, may " 71 "reduce static noise."); 72 73module_param(shutdown, bool, 0644); 74MODULE_PARM_DESC(shutdown, "Enable shutting down PLL and muting line when " 75 "module is unloaded."); 76 77module_param(keepmuted, bool, 0644); 78MODULE_PARM_DESC(keepmuted, "Keep card muted even when frequency is changed."); 79 80module_param(initmute, bool, 0444); 81MODULE_PARM_DESC(initmute, "Mute card when module is loaded."); 82 83module_param(radio_nr, int, 0444); 84 85/* 86 * Functions for controlling the card. 87 */ 88#define GEMTEK_LOWFREQ (87*16000) 89#define GEMTEK_HIGHFREQ (108*16000) 90 91/* 92 * Frequency calculation constants. Intermediate frequency 10.52 MHz (nominal 93 * value 10.7 MHz), reference divisor 6.39 kHz (nominal 6.25 kHz). 94 */ 95#define FSCALE 8 96#define IF_OFFSET ((unsigned int)(10.52 * 16000 * (1<<FSCALE))) 97#define REF_FREQ ((unsigned int)(6.39 * 16 * (1<<FSCALE))) 98 99#define GEMTEK_CK 0x01 /* Clock signal */ 100#define GEMTEK_DA 0x02 /* Serial data */ 101#define GEMTEK_CE 0x04 /* Chip enable */ 102#define GEMTEK_NS 0x08 /* No signal */ 103#define GEMTEK_MT 0x10 /* Line mute */ 104#define GEMTEK_STDF_3_125_KHZ 0x01 /* Standard frequency 3.125 kHz */ 105#define GEMTEK_PLL_OFF 0x07 /* PLL off */ 106 107#define BU2614_BUS_SIZE 32 /* BU2614 / BU2614FS bus size */ 108 109#define SHORT_DELAY 5 /* usec */ 110#define LONG_DELAY 75 /* usec */ 111 112struct gemtek { 113 struct v4l2_device v4l2_dev; 114 struct video_device vdev; 115 struct mutex lock; 116 unsigned long lastfreq; 117 int muted; 118 int verified; 119 int io; 120 u32 bu2614data; 121}; 122 123static struct gemtek gemtek_card; 124 125#define BU2614_FREQ_BITS 16 /* D0..D15, Frequency data */ 126#define BU2614_PORT_BITS 3 /* P0..P2, Output port control data */ 127#define BU2614_VOID_BITS 4 /* unused */ 128#define BU2614_FMES_BITS 1 /* CT, Frequency measurement beginning data */ 129#define BU2614_STDF_BITS 3 /* R0..R2, Standard frequency data */ 130#define BU2614_SWIN_BITS 1 /* S, Switch between FMIN / AMIN */ 131#define BU2614_SWAL_BITS 1 /* PS, Swallow counter division (AMIN only)*/ 132#define BU2614_VOID2_BITS 1 /* unused */ 133#define BU2614_FMUN_BITS 1 /* GT, Frequency measurement time & unlock */ 134#define BU2614_TEST_BITS 1 /* TS, Test data is input */ 135 136#define BU2614_FREQ_SHIFT 0 137#define BU2614_PORT_SHIFT (BU2614_FREQ_BITS + BU2614_FREQ_SHIFT) 138#define BU2614_VOID_SHIFT (BU2614_PORT_BITS + BU2614_PORT_SHIFT) 139#define BU2614_FMES_SHIFT (BU2614_VOID_BITS + BU2614_VOID_SHIFT) 140#define BU2614_STDF_SHIFT (BU2614_FMES_BITS + BU2614_FMES_SHIFT) 141#define BU2614_SWIN_SHIFT (BU2614_STDF_BITS + BU2614_STDF_SHIFT) 142#define BU2614_SWAL_SHIFT (BU2614_SWIN_BITS + BU2614_SWIN_SHIFT) 143#define BU2614_VOID2_SHIFT (BU2614_SWAL_BITS + BU2614_SWAL_SHIFT) 144#define BU2614_FMUN_SHIFT (BU2614_VOID2_BITS + BU2614_VOID2_SHIFT) 145#define BU2614_TEST_SHIFT (BU2614_FMUN_BITS + BU2614_FMUN_SHIFT) 146 147#define MKMASK(field) (((1<<BU2614_##field##_BITS) - 1) << \ 148 BU2614_##field##_SHIFT) 149#define BU2614_PORT_MASK MKMASK(PORT) 150#define BU2614_FREQ_MASK MKMASK(FREQ) 151#define BU2614_VOID_MASK MKMASK(VOID) 152#define BU2614_FMES_MASK MKMASK(FMES) 153#define BU2614_STDF_MASK MKMASK(STDF) 154#define BU2614_SWIN_MASK MKMASK(SWIN) 155#define BU2614_SWAL_MASK MKMASK(SWAL) 156#define BU2614_VOID2_MASK MKMASK(VOID2) 157#define BU2614_FMUN_MASK MKMASK(FMUN) 158#define BU2614_TEST_MASK MKMASK(TEST) 159 160/* 161 * Set data which will be sent to BU2614FS. 162 */ 163#define gemtek_bu2614_set(dev, field, data) ((dev)->bu2614data = \ 164 ((dev)->bu2614data & ~field##_MASK) | ((data) << field##_SHIFT)) 165 166/* 167 * Transmit settings to BU2614FS over GemTek IC. 168 */ 169static void gemtek_bu2614_transmit(struct gemtek *gt) 170{ 171 int i, bit, q, mute; 172 173 mutex_lock(>->lock); 174 175 mute = gt->muted ? GEMTEK_MT : 0x00; 176 177 outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io); 178 udelay(SHORT_DELAY); 179 outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io); 180 udelay(LONG_DELAY); 181 182 for (i = 0, q = gt->bu2614data; i < 32; i++, q >>= 1) { 183 bit = (q & 1) ? GEMTEK_DA : 0; 184 outb_p(mute | GEMTEK_CE | bit, gt->io); 185 udelay(SHORT_DELAY); 186 outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, gt->io); 187 udelay(SHORT_DELAY); 188 } 189 190 outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io); 191 udelay(SHORT_DELAY); 192 outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io); 193 udelay(LONG_DELAY); 194 195 mutex_unlock(>->lock); 196} 197 198/* 199 * Calculate divisor from FM-frequency for BU2614FS (3.125 KHz STDF expected). 200 */ 201static unsigned long gemtek_convfreq(unsigned long freq) 202{ 203 return ((freq<<FSCALE) + IF_OFFSET + REF_FREQ/2) / REF_FREQ; 204} 205 206/* 207 * Set FM-frequency. 208 */ 209static void gemtek_setfreq(struct gemtek *gt, unsigned long freq) 210{ 211 if (keepmuted && hardmute && gt->muted) 212 return; 213 214 freq = clamp_val(freq, GEMTEK_LOWFREQ, GEMTEK_HIGHFREQ); 215 216 gt->lastfreq = freq; 217 gt->muted = 0; 218 219 gemtek_bu2614_set(gt, BU2614_PORT, 0); 220 gemtek_bu2614_set(gt, BU2614_FMES, 0); 221 gemtek_bu2614_set(gt, BU2614_SWIN, 0); /* FM-mode */ 222 gemtek_bu2614_set(gt, BU2614_SWAL, 0); 223 gemtek_bu2614_set(gt, BU2614_FMUN, 1); /* GT bit set */ 224 gemtek_bu2614_set(gt, BU2614_TEST, 0); 225 226 gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_STDF_3_125_KHZ); 227 gemtek_bu2614_set(gt, BU2614_FREQ, gemtek_convfreq(freq)); 228 229 gemtek_bu2614_transmit(gt); 230} 231 232/* 233 * Set mute flag. 234 */ 235static void gemtek_mute(struct gemtek *gt) 236{ 237 int i; 238 239 gt->muted = 1; 240 241 if (hardmute) { 242 /* Turn off PLL, disable data output */ 243 gemtek_bu2614_set(gt, BU2614_PORT, 0); 244 gemtek_bu2614_set(gt, BU2614_FMES, 0); /* CT bit off */ 245 gemtek_bu2614_set(gt, BU2614_SWIN, 0); /* FM-mode */ 246 gemtek_bu2614_set(gt, BU2614_SWAL, 0); 247 gemtek_bu2614_set(gt, BU2614_FMUN, 0); /* GT bit off */ 248 gemtek_bu2614_set(gt, BU2614_TEST, 0); 249 gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_PLL_OFF); 250 gemtek_bu2614_set(gt, BU2614_FREQ, 0); 251 gemtek_bu2614_transmit(gt); 252 return; 253 } 254 255 mutex_lock(>->lock); 256 257 /* Read bus contents (CE, CK and DA). */ 258 i = inb_p(gt->io); 259 /* Write it back with mute flag set. */ 260 outb_p((i >> 5) | GEMTEK_MT, gt->io); 261 udelay(SHORT_DELAY); 262 263 mutex_unlock(>->lock); 264} 265 266/* 267 * Unset mute flag. 268 */ 269static void gemtek_unmute(struct gemtek *gt) 270{ 271 int i; 272 273 gt->muted = 0; 274 if (hardmute) { 275 /* Turn PLL back on. */ 276 gemtek_setfreq(gt, gt->lastfreq); 277 return; 278 } 279 mutex_lock(>->lock); 280 281 i = inb_p(gt->io); 282 outb_p(i >> 5, gt->io); 283 udelay(SHORT_DELAY); 284 285 mutex_unlock(>->lock); 286} 287 288/* 289 * Get signal strength (= stereo status). 290 */ 291static inline int gemtek_getsigstr(struct gemtek *gt) 292{ 293 int sig; 294 295 mutex_lock(>->lock); 296 sig = inb_p(gt->io) & GEMTEK_NS ? 0 : 1; 297 mutex_unlock(>->lock); 298 return sig; 299} 300 301/* 302 * Check if requested card acts like GemTek Radio card. 303 */ 304static int gemtek_verify(struct gemtek *gt, int port) 305{ 306 int i, q; 307 308 if (gt->verified == port) 309 return 1; 310 311 mutex_lock(>->lock); 312 313 q = inb_p(port); /* Read bus contents before probing. */ 314 /* Try to turn on CE, CK and DA respectively and check if card responds 315 properly. */ 316 for (i = 0; i < 3; ++i) { 317 outb_p(1 << i, port); 318 udelay(SHORT_DELAY); 319 320 if ((inb_p(port) & (~GEMTEK_NS)) != (0x17 | (1 << (i + 5)))) { 321 mutex_unlock(>->lock); 322 return 0; 323 } 324 } 325 outb_p(q >> 5, port); /* Write bus contents back. */ 326 udelay(SHORT_DELAY); 327 328 mutex_unlock(>->lock); 329 gt->verified = port; 330 331 return 1; 332} 333 334/* 335 * Automatic probing for card. 336 */ 337static int gemtek_probe(struct gemtek *gt) 338{ 339 struct v4l2_device *v4l2_dev = >->v4l2_dev; 340 int ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c }; 341 int i; 342 343 if (!probe) { 344 v4l2_info(v4l2_dev, "Automatic device probing disabled.\n"); 345 return -1; 346 } 347 348 v4l2_info(v4l2_dev, "Automatic device probing enabled.\n"); 349 350 for (i = 0; i < ARRAY_SIZE(ioports); ++i) { 351 v4l2_info(v4l2_dev, "Trying I/O port 0x%x...\n", ioports[i]); 352 353 if (!request_region(ioports[i], 1, "gemtek-probe")) { 354 v4l2_warn(v4l2_dev, "I/O port 0x%x busy!\n", 355 ioports[i]); 356 continue; 357 } 358 359 if (gemtek_verify(gt, ioports[i])) { 360 v4l2_info(v4l2_dev, "Card found from I/O port " 361 "0x%x!\n", ioports[i]); 362 363 release_region(ioports[i], 1); 364 gt->io = ioports[i]; 365 return gt->io; 366 } 367 368 release_region(ioports[i], 1); 369 } 370 371 v4l2_err(v4l2_dev, "Automatic probing failed!\n"); 372 return -1; 373} 374 375/* 376 * Video 4 Linux stuff. 377 */ 378 379static const struct v4l2_file_operations gemtek_fops = { 380 .owner = THIS_MODULE, 381 .ioctl = video_ioctl2, 382}; 383 384static int vidioc_querycap(struct file *file, void *priv, 385 struct v4l2_capability *v) 386{ 387 strlcpy(v->driver, "radio-gemtek", sizeof(v->driver)); 388 strlcpy(v->card, "GemTek", sizeof(v->card)); 389 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); 390 v->version = RADIO_VERSION; 391 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 392 return 0; 393} 394 395static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) 396{ 397 struct gemtek *gt = video_drvdata(file); 398 399 if (v->index > 0) 400 return -EINVAL; 401 402 strlcpy(v->name, "FM", sizeof(v->name)); 403 v->type = V4L2_TUNER_RADIO; 404 v->rangelow = GEMTEK_LOWFREQ; 405 v->rangehigh = GEMTEK_HIGHFREQ; 406 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; 407 v->signal = 0xffff * gemtek_getsigstr(gt); 408 if (v->signal) { 409 v->audmode = V4L2_TUNER_MODE_STEREO; 410 v->rxsubchans = V4L2_TUNER_SUB_STEREO; 411 } else { 412 v->audmode = V4L2_TUNER_MODE_MONO; 413 v->rxsubchans = V4L2_TUNER_SUB_MONO; 414 } 415 return 0; 416} 417 418static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) 419{ 420 return (v->index != 0) ? -EINVAL : 0; 421} 422 423static int vidioc_g_frequency(struct file *file, void *priv, 424 struct v4l2_frequency *f) 425{ 426 struct gemtek *gt = video_drvdata(file); 427 428 if (f->tuner != 0) 429 return -EINVAL; 430 f->type = V4L2_TUNER_RADIO; 431 f->frequency = gt->lastfreq; 432 return 0; 433} 434 435static int vidioc_s_frequency(struct file *file, void *priv, 436 struct v4l2_frequency *f) 437{ 438 struct gemtek *gt = video_drvdata(file); 439 440 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 441 return -EINVAL; 442 gemtek_setfreq(gt, f->frequency); 443 return 0; 444} 445 446static int vidioc_queryctrl(struct file *file, void *priv, 447 struct v4l2_queryctrl *qc) 448{ 449 switch (qc->id) { 450 case V4L2_CID_AUDIO_MUTE: 451 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); 452 default: 453 return -EINVAL; 454 } 455} 456 457static int vidioc_g_ctrl(struct file *file, void *priv, 458 struct v4l2_control *ctrl) 459{ 460 struct gemtek *gt = video_drvdata(file); 461 462 switch (ctrl->id) { 463 case V4L2_CID_AUDIO_MUTE: 464 ctrl->value = gt->muted; 465 return 0; 466 } 467 return -EINVAL; 468} 469 470static int vidioc_s_ctrl(struct file *file, void *priv, 471 struct v4l2_control *ctrl) 472{ 473 struct gemtek *gt = video_drvdata(file); 474 475 switch (ctrl->id) { 476 case V4L2_CID_AUDIO_MUTE: 477 if (ctrl->value) 478 gemtek_mute(gt); 479 else 480 gemtek_unmute(gt); 481 return 0; 482 } 483 return -EINVAL; 484} 485 486static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 487{ 488 *i = 0; 489 return 0; 490} 491 492static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 493{ 494 return (i != 0) ? -EINVAL : 0; 495} 496 497static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) 498{ 499 a->index = 0; 500 strlcpy(a->name, "Radio", sizeof(a->name)); 501 a->capability = V4L2_AUDCAP_STEREO; 502 return 0; 503} 504 505static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) 506{ 507 return (a->index != 0) ? -EINVAL : 0; 508} 509 510static const struct v4l2_ioctl_ops gemtek_ioctl_ops = { 511 .vidioc_querycap = vidioc_querycap, 512 .vidioc_g_tuner = vidioc_g_tuner, 513 .vidioc_s_tuner = vidioc_s_tuner, 514 .vidioc_g_audio = vidioc_g_audio, 515 .vidioc_s_audio = vidioc_s_audio, 516 .vidioc_g_input = vidioc_g_input, 517 .vidioc_s_input = vidioc_s_input, 518 .vidioc_g_frequency = vidioc_g_frequency, 519 .vidioc_s_frequency = vidioc_s_frequency, 520 .vidioc_queryctrl = vidioc_queryctrl, 521 .vidioc_g_ctrl = vidioc_g_ctrl, 522 .vidioc_s_ctrl = vidioc_s_ctrl 523}; 524 525/* 526 * Initialization / cleanup related stuff. 527 */ 528 529static int __init gemtek_init(void) 530{ 531 struct gemtek *gt = &gemtek_card; 532 struct v4l2_device *v4l2_dev = >->v4l2_dev; 533 int res; 534 535 strlcpy(v4l2_dev->name, "gemtek", sizeof(v4l2_dev->name)); 536 537 v4l2_info(v4l2_dev, "GemTek Radio card driver: v0.0.3\n"); 538 539 mutex_init(>->lock); 540 541 gt->verified = -1; 542 gt->io = io; 543 gemtek_probe(gt); 544 if (gt->io) { 545 if (!request_region(gt->io, 1, "gemtek")) { 546 v4l2_err(v4l2_dev, "I/O port 0x%x already in use.\n", gt->io); 547 return -EBUSY; 548 } 549 550 if (!gemtek_verify(gt, gt->io)) 551 v4l2_warn(v4l2_dev, "Card at I/O port 0x%x does not " 552 "respond properly, check your " 553 "configuration.\n", gt->io); 554 else 555 v4l2_info(v4l2_dev, "Using I/O port 0x%x.\n", gt->io); 556 } else if (probe) { 557 v4l2_err(v4l2_dev, "Automatic probing failed and no " 558 "fixed I/O port defined.\n"); 559 return -ENODEV; 560 } else { 561 v4l2_err(v4l2_dev, "Automatic probing disabled but no fixed " 562 "I/O port defined."); 563 return -EINVAL; 564 } 565 566 res = v4l2_device_register(NULL, v4l2_dev); 567 if (res < 0) { 568 v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 569 release_region(gt->io, 1); 570 return res; 571 } 572 573 strlcpy(gt->vdev.name, v4l2_dev->name, sizeof(gt->vdev.name)); 574 gt->vdev.v4l2_dev = v4l2_dev; 575 gt->vdev.fops = &gemtek_fops; 576 gt->vdev.ioctl_ops = &gemtek_ioctl_ops; 577 gt->vdev.release = video_device_release_empty; 578 video_set_drvdata(>->vdev, gt); 579 580 if (video_register_device(>->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { 581 v4l2_device_unregister(v4l2_dev); 582 release_region(gt->io, 1); 583 return -EBUSY; 584 } 585 586 /* Set defaults */ 587 gt->lastfreq = GEMTEK_LOWFREQ; 588 gt->bu2614data = 0; 589 590 if (initmute) 591 gemtek_mute(gt); 592 593 return 0; 594} 595 596/* 597 * Module cleanup 598 */ 599static void __exit gemtek_exit(void) 600{ 601 struct gemtek *gt = &gemtek_card; 602 struct v4l2_device *v4l2_dev = >->v4l2_dev; 603 604 if (shutdown) { 605 hardmute = 1; /* Turn off PLL */ 606 gemtek_mute(gt); 607 } else { 608 v4l2_info(v4l2_dev, "Module unloaded but card not muted!\n"); 609 } 610 611 video_unregister_device(>->vdev); 612 v4l2_device_unregister(>->v4l2_dev); 613 release_region(gt->io, 1); 614} 615 616module_init(gemtek_init); 617module_exit(gemtek_exit); 618