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