Date: Tue, 25 Jun 2002 07:46:45 -0400 (EDT) From: Bryan Liesner <bleez@bellatlantic.net> To: freebsd-stable@freebsd.org Subject: D-Link DSB-R100 and the ufm driver Message-ID: <20020625073327.D708-200000@gravy.kishka.net>
index | next in thread | raw e-mail
[-- Attachment #1 --]
I just finished compiling ufm support into the kernel, and grabbed
NetBSD's dsbr100 port to control my DSB-R100 device. With a little
tweaking I got the port to compile, but when I run it I get
inappropriate ioctl errors for USB_GET_DEVICEINFO and
USB_DO_REQUEST.
I think the device node may be wrong but here's what I have:
crw-r--r-- 1 root operator 200, 0 Jun 25 00:55 /dev/ufm0
dmesg shows:
ufm0: GemTek Corp USB FM Radio, rev 1.00/4.10, addr 2
I'm definitely not a USB guru, and need a bit of help getting this
thing to work. The source is small enough, so it's attached.
Thanks!
==========================================================
= Bryan D. Liesner LeezSoft Communications, Inc. =
= A subsidiary of LeezSoft Inc. =
= bleez@bellatlantic.net Home of the Gipper =
==========================================================
[-- Attachment #2 --]
/*
* Copyright (c) 2000 Lennart Augustsson <augustss@netbsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* A driver for the D-Link DSB-R100 USB radio. The radio plugs
* into both the USB and an analog audio input. The USB part
* only deals with initialisation and frequency setting, the
* audio data has to be handled by a sound driver.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <err.h>
#include <dev/usb/usb.h>
#include <sys/ioctl.h>
#define VENDOR 0x04b4
#define PRODUCT 0x1002
int debug = 0;
int verbose = 0;
int autotune = 1;
int delta = 50;
int minstep = 10;
int sleeptime = 300000;
#define DEFAULT_DEV "/dev/ufm0"
int
radio_req(int f, int ureq, int value, int index)
{
struct usb_ctl_request req;
u_char data;
int r;
req.ucr_request.bmRequestType = UT_READ_VENDOR_DEVICE;
req.ucr_request.bRequest = ureq;
USETW(req.ucr_request.wValue, value);
USETW(req.ucr_request.wIndex, index);
USETW(req.ucr_request.wLength, 1);
req.ucr_data = &data;
req.ucr_flags = 0; //USBD_SHORT_XFER_OK;
r = ioctl(f, USB_DO_REQUEST, &req);
if (r < 0)
err(1, "USB_DO_REQUEST");
if (debug > 1)
printf("%#x %#x %#x %#x len=%d\n", ureq, UT_READ_VENDOR_DEVICE,
value, index, req.ucr_actlen);
return !(data & 1);
}
void
radio_start(int f)
{
radio_req(f, 0x00, 0x0000, 0x00c7);
radio_req(f, 0x02, 0x0001, 0x0000);
}
void
radio_stop(int f)
{
radio_req(f, 0x00, 0x0016, 0x001c);
radio_req(f, 0x02, 0x0000, 0x0000);
}
void
radio_setfreq(int f, int freq)
{
if (debug > 1) printf("setfreq=%d\n", freq);
freq = freq * 80 / 1000 + 856;
if (debug > 2) printf("freq = %#x\n", freq);
radio_req(f, 0x01, (freq >> 8) & 0xff, freq & 0xff);
radio_req(f, 0x00, 0x0096, 0x00b7);
radio_req(f, 0x00, 0x0000, 0x0024);
}
int
radio_status(int f)
{
return radio_req(f, 0x00, 0x0000, 0x0024);
}
void
usage(void)
{
extern char *__progname;
fprintf(stderr, "Usage: %s [-f device] [-v] start\n", __progname);
fprintf(stderr, " %s [-f device] [-v] stop\n", __progname);
fprintf(stderr, " %s [-f device] [-v] status\n", __progname);
fprintf(stderr, " %s [-f device] [-v] [-n] <freq>\n", __progname);
fprintf(stderr, " %s [-f device] [-v] [-n] scan <lo> <hi>\n", __progname);
fprintf(stderr, " %s [-f device] [-v] [-n] search <lo> <hi>\n", __progname);
exit(1);
}
void
setfreq(int f, int fr)
{
int s, slo, shi;
int nacc, acc;
if (!autotune) {
radio_setfreq(f, fr);
usleep(sleeptime);
return;
}
slo = fr - 4 * delta / 2;
shi = fr + 4 * delta / 2;
acc = fr;
nacc = 1;
for (s = slo; s <= shi; s += minstep) {
radio_setfreq(f, s);
usleep(sleeptime);
if(debug)
printf("try freq=%d stereo=%d\n", s, radio_status(f));
if (radio_status(f)) {
acc += s;
nacc++;
}
}
acc /= nacc;
if (debug)
printf("freq=%d\n", acc);
radio_setfreq(f, acc);
usleep(sleeptime);
}
void
scan(int f, int lo, int hi, int cont)
{
int fr;
for (;;) {
for (fr = lo; fr < hi; fr += delta) {
if (verbose)
printf("\r%.2f", fr / 1000.0), fflush(stdout);
radio_setfreq(f, fr);
usleep(sleeptime);
if (radio_status(f)) {
setfreq(f, fr + delta);
if (verbose)
printf("\n");
else
printf("%.2f\n", fr / 1000.0);
if (!cont)
return;
sleep(5);
}
fr += 3 * delta;
}
}
}
int
main(int argc, char **argv)
{
char *dev = 0;
char devbuf[1024];
int f, ch;
double freq, lo, hi;
struct usb_device_info di;
while ((ch = getopt(argc, argv, "df:nv")) != -1) {
switch(ch) {
case 'd':
debug++;
break;
case 'f':
dev = optarg;
break;
case 'n':
autotune = 0;
break;
case 'v':
verbose++;
break;
case '?':
default:
usage();
}
}
argc -= optind;
argv += optind;
if (!dev)
dev = DEFAULT_DEV;
f = open(dev, O_RDWR);
if (f < 0) {
if (dev[0] != '/') {
sprintf(devbuf, "/dev/%s", dev);
f = open(devbuf, O_RDWR);
} else
strcpy(devbuf, dev);
if (f < 0) {
if (!strchr(devbuf, '.')) {
strcat(devbuf, ".00");
f = open(devbuf, O_RDWR);
}
}
}
if (f < 0)
err(1, "%s", dev);
if (ioctl(f, USB_GET_DEVICEINFO, &di) != 0)
err(1, "USB_GET_DEVICEINFO");
if (verbose > 1) {
printf("Product: %s\n", di.udi_product);
printf("Vendor: %s\n", di.udi_vendor);
}
if (di.udi_vendorNo != VENDOR || di.udi_productNo != PRODUCT)
errx(1, "The device is not a DSB-R100 radio\n");
if (argc == 1 && strcmp(argv[0], "start") == 0)
radio_start(f);
else if (argc == 1 && strcmp(argv[0], "stop") == 0)
radio_stop(f);
else if (argc == 1 && sscanf(argv[0], "%lf", &freq) == 1) {
setfreq(f, (int)(freq * 1000));
if(verbose)
printf("%s\n", radio_status(f) ? "stereo" : "mono");
} else if (argc == 3 && strcmp(argv[0], "scan") == 0 &&
sscanf(argv[1], "%lf", &lo) == 1 &&
sscanf(argv[2], "%lf", &hi) == 1) {
scan(f, lo * 1000, hi * 1000, 1);
} else if (argc == 3 && strcmp(argv[0], "search") == 0 &&
sscanf(argv[1], "%lf", &lo) == 1 &&
sscanf(argv[2], "%lf", &hi) == 1) {
scan(f, lo * 1000, hi * 1000, 0);
} else if (argc == 1 && strcmp(argv[0], "status") == 0)
printf("%s\n", radio_status(f) ? "stereo" : "mono");
else
usage();
close(f);
exit(0);
}
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020625073327.D708-200000>
