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 36 MODULE_AUTHOR("Jonas Munsin, Pekka Sepp�nen <pexu@kapsi.fi>"); 37 MODULE_DESCRIPTION("A driver for the GemTek Radio card."); 38 MODULE_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 51 static int io = CONFIG_RADIO_GEMTEK_PORT; 52 static int probe = CONFIG_RADIO_GEMTEK_PROBE; 53 static int hardmute; 54 static int shutdown = 1; 55 static int keepmuted = 1; 56 static int initmute = 1; 57 static int radio_nr = -1; 58 59 module_param(io, int, 0444); 60 MODULE_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 65 module_param(probe, bool, 0444); 66 MODULE_PARM_DESC(probe, "Enable automatic device probing. Note: only the most " 67 "common I/O ports used by the card are probed."); 68 69 module_param(hardmute, bool, 0644); 70 MODULE_PARM_DESC(hardmute, "Enable `hard muting' by shutting down PLL, may " 71 "reduce static noise."); 72 73 module_param(shutdown, bool, 0644); 74 MODULE_PARM_DESC(shutdown, "Enable shutting down PLL and muting line when " 75 "module is unloaded."); 76 77 module_param(keepmuted, bool, 0644); 78 MODULE_PARM_DESC(keepmuted, "Keep card muted even when frequency is changed."); 79 80 module_param(initmute, bool, 0444); 81 MODULE_PARM_DESC(initmute, "Mute card when module is loaded."); 82 83 module_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 112 struct 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 123 static 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 */ 169 static 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 */ 201 static 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 */ 209 static 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 */ 235 static 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 */ 269 static 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 */ 291 static 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 */ 304 static 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 */ 337 static 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 static int gemtek_open(struct file *file) 379 { 380 return 0; 381 } 382 383 static int gemtek_release(struct file *file) 384 { 385 return 0; 386 } 387 388 static const struct v4l2_file_operations gemtek_fops = { 389 .owner = THIS_MODULE, 390 .open = gemtek_open, 391 .release = gemtek_release, 392 .ioctl = video_ioctl2, 393 }; 394 395 static int vidioc_querycap(struct file *file, void *priv, 396 struct v4l2_capability *v) 397 { 398 strlcpy(v->driver, "radio-gemtek", sizeof(v->driver)); 399 strlcpy(v->card, "GemTek", sizeof(v->card)); 400 strlcpy(v->bus_info, "ISA", sizeof(v->bus_info)); 401 v->version = RADIO_VERSION; 402 v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; 403 return 0; 404 } 405 406 static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) 407 { 408 struct gemtek *gt = video_drvdata(file); 409 410 if (v->index > 0) 411 return -EINVAL; 412 413 strlcpy(v->name, "FM", sizeof(v->name)); 414 v->type = V4L2_TUNER_RADIO; 415 v->rangelow = GEMTEK_LOWFREQ; 416 v->rangehigh = GEMTEK_HIGHFREQ; 417 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; 418 v->signal = 0xffff * gemtek_getsigstr(gt); 419 if (v->signal) { 420 v->audmode = V4L2_TUNER_MODE_STEREO; 421 v->rxsubchans = V4L2_TUNER_SUB_STEREO; 422 } else { 423 v->audmode = V4L2_TUNER_MODE_MONO; 424 v->rxsubchans = V4L2_TUNER_SUB_MONO; 425 } 426 return 0; 427 } 428 429 static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v) 430 { 431 return (v->index != 0) ? -EINVAL : 0; 432 } 433 434 static int vidioc_g_frequency(struct file *file, void *priv, 435 struct v4l2_frequency *f) 436 { 437 struct gemtek *gt = video_drvdata(file); 438 439 if (f->tuner != 0) 440 return -EINVAL; 441 f->type = V4L2_TUNER_RADIO; 442 f->frequency = gt->lastfreq; 443 return 0; 444 } 445 446 static int vidioc_s_frequency(struct file *file, void *priv, 447 struct v4l2_frequency *f) 448 { 449 struct gemtek *gt = video_drvdata(file); 450 451 if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) 452 return -EINVAL; 453 gemtek_setfreq(gt, f->frequency); 454 return 0; 455 } 456 457 static int vidioc_queryctrl(struct file *file, void *priv, 458 struct v4l2_queryctrl *qc) 459 { 460 switch (qc->id) { 461 case V4L2_CID_AUDIO_MUTE: 462 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0); 463 default: 464 return -EINVAL; 465 } 466 } 467 468 static int vidioc_g_ctrl(struct file *file, void *priv, 469 struct v4l2_control *ctrl) 470 { 471 struct gemtek *gt = video_drvdata(file); 472 473 switch (ctrl->id) { 474 case V4L2_CID_AUDIO_MUTE: 475 ctrl->value = gt->muted; 476 return 0; 477 } 478 return -EINVAL; 479 } 480 481 static int vidioc_s_ctrl(struct file *file, void *priv, 482 struct v4l2_control *ctrl) 483 { 484 struct gemtek *gt = video_drvdata(file); 485 486 switch (ctrl->id) { 487 case V4L2_CID_AUDIO_MUTE: 488 if (ctrl->value) 489 gemtek_mute(gt); 490 else 491 gemtek_unmute(gt); 492 return 0; 493 } 494 return -EINVAL; 495 } 496 497 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 498 { 499 *i = 0; 500 return 0; 501 } 502 503 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 504 { 505 return (i != 0) ? -EINVAL : 0; 506 } 507 508 static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) 509 { 510 a->index = 0; 511 strlcpy(a->name, "Radio", sizeof(a->name)); 512 a->capability = V4L2_AUDCAP_STEREO; 513 return 0; 514 } 515 516 static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) 517 { 518 return (a->index != 0) ? -EINVAL : 0; 519 } 520 521 static const struct v4l2_ioctl_ops gemtek_ioctl_ops = { 522 .vidioc_querycap = vidioc_querycap, 523 .vidioc_g_tuner = vidioc_g_tuner, 524 .vidioc_s_tuner = vidioc_s_tuner, 525 .vidioc_g_audio = vidioc_g_audio, 526 .vidioc_s_audio = vidioc_s_audio, 527 .vidioc_g_input = vidioc_g_input, 528 .vidioc_s_input = vidioc_s_input, 529 .vidioc_g_frequency = vidioc_g_frequency, 530 .vidioc_s_frequency = vidioc_s_frequency, 531 .vidioc_queryctrl = vidioc_queryctrl, 532 .vidioc_g_ctrl = vidioc_g_ctrl, 533 .vidioc_s_ctrl = vidioc_s_ctrl 534 }; 535 536 /* 537 * Initialization / cleanup related stuff. 538 */ 539 540 static int __init gemtek_init(void) 541 { 542 struct gemtek *gt = &gemtek_card; 543 struct v4l2_device *v4l2_dev = >->v4l2_dev; 544 int res; 545 546 strlcpy(v4l2_dev->name, "gemtek", sizeof(v4l2_dev->name)); 547 548 v4l2_info(v4l2_dev, "GemTek Radio card driver: v0.0.3\n"); 549 550 mutex_init(>->lock); 551 552 gt->verified = -1; 553 gt->io = io; 554 gemtek_probe(gt); 555 if (gt->io) { 556 if (!request_region(gt->io, 1, "gemtek")) { 557 v4l2_err(v4l2_dev, "I/O port 0x%x already in use.\n", gt->io); 558 return -EBUSY; 559 } 560 561 if (!gemtek_verify(gt, gt->io)) 562 v4l2_warn(v4l2_dev, "Card at I/O port 0x%x does not " 563 "respond properly, check your " 564 "configuration.\n", gt->io); 565 else 566 v4l2_info(v4l2_dev, "Using I/O port 0x%x.\n", gt->io); 567 } else if (probe) { 568 v4l2_err(v4l2_dev, "Automatic probing failed and no " 569 "fixed I/O port defined.\n"); 570 return -ENODEV; 571 } else { 572 v4l2_err(v4l2_dev, "Automatic probing disabled but no fixed " 573 "I/O port defined."); 574 return -EINVAL; 575 } 576 577 res = v4l2_device_register(NULL, v4l2_dev); 578 if (res < 0) { 579 v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 580 release_region(gt->io, 1); 581 return res; 582 } 583 584 strlcpy(gt->vdev.name, v4l2_dev->name, sizeof(gt->vdev.name)); 585 gt->vdev.v4l2_dev = v4l2_dev; 586 gt->vdev.fops = &gemtek_fops; 587 gt->vdev.ioctl_ops = &gemtek_ioctl_ops; 588 gt->vdev.release = video_device_release_empty; 589 video_set_drvdata(>->vdev, gt); 590 591 if (video_register_device(>->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { 592 v4l2_device_unregister(v4l2_dev); 593 release_region(gt->io, 1); 594 return -EBUSY; 595 } 596 597 /* Set defaults */ 598 gt->lastfreq = GEMTEK_LOWFREQ; 599 gt->bu2614data = 0; 600 601 if (initmute) 602 gemtek_mute(gt); 603 604 return 0; 605 } 606 607 /* 608 * Module cleanup 609 */ 610 static void __exit gemtek_exit(void) 611 { 612 struct gemtek *gt = &gemtek_card; 613 struct v4l2_device *v4l2_dev = >->v4l2_dev; 614 615 if (shutdown) { 616 hardmute = 1; /* Turn off PLL */ 617 gemtek_mute(gt); 618 } else { 619 v4l2_info(v4l2_dev, "Module unloaded but card not muted!\n"); 620 } 621 622 video_unregister_device(>->vdev); 623 v4l2_device_unregister(>->v4l2_dev); 624 release_region(gt->io, 1); 625 } 626 627 module_init(gemtek_init); 628 module_exit(gemtek_exit); 629