Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev Add slurm(4), a radio(4) driver for USB FM radio mod...



details:   https://anonhg.NetBSD.org/src/rev/5c1b6ca3032d
branches:  trunk
changeset: 783943:5c1b6ca3032d
user:      jakllsch <jakllsch%NetBSD.org@localhost>
date:      Sun Jan 13 01:15:02 2013 +0000

description:
Add slurm(4), a radio(4) driver for USB FM radio modules based on the
Silicon Labs reference design.

diffstat:

 sys/dev/ic/si470x_reg.h       |  112 ++++++++++++
 sys/dev/usb/files.usb         |    7 +-
 sys/dev/usb/slurm.c           |  379 ++++++++++++++++++++++++++++++++++++++++++
 sys/dev/usb/usbdevices.config |    6 +-
 4 files changed, 502 insertions(+), 2 deletions(-)

diffs (truncated from 540 to 300 lines):

diff -r 96e982d091ed -r 5c1b6ca3032d sys/dev/ic/si470x_reg.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/ic/si470x_reg.h   Sun Jan 13 01:15:02 2013 +0000
@@ -0,0 +1,112 @@
+/*     $NetBSD: si470x_reg.h,v 1.1 2013/01/13 01:15:02 jakllsch Exp $ */
+
+/*
+ * Copyright (c) 2012 Jonathan A. Kollasch
+ * 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+ */
+
+#ifndef _DEV_IC_SI470X_REG_H_
+#define _DEV_IC_SI470X_REG_H_
+
+#define __BIT16(x)             ((uint16_t)__BIT(x))
+#define __BITS16(x, y)         ((uint16_t)__BITS((x), (y)))
+
+#define SI470X_DEVICEID                0x00
+#define SI470X_PN              __BITS16(15, 12)
+#define SI470X_MFGID           __BITS16(11, 0)
+
+#define SI470X_CHIPID          0x01
+#define SI470X_REV             __BITS16(15, 10)
+#define SI470X_DEV             __BITS16(9, 6)
+#define SI470X_FIRMWARE                __BITS16(5, 0)
+
+#define SI470X_POWERCFG                0x02
+#define SI470X_DSMUTE          __BIT16(15)
+#define SI470X_DMUTE           __BIT16(14)
+#define SI470X_MONO            __BIT16(13)
+#define SI470X_RDSM            __BIT16(11)
+#define SI470X_SKMODE          __BIT16(10)
+#define SI470X_SEEKUP          __BIT16(9)
+#define SI470X_SEEK            __BIT16(8)
+#define SI470X_DISABLE         __BIT16(6)
+#define SI470X_ENABLE          __BIT16(0)
+
+#define SI470X_CHANNEL         0x03
+#define SI470X_TUNE            __BIT16(15)
+#define SI470X_CHAN            __BITS16(9, 0)
+
+#define SI470X_SYSCONFIG1      0x04
+#define SI470X_RDSIEN          __BIT16(15)
+#define SI470X_STCIEN          __BIT16(14)
+#define SI470X_RDS             __BIT16(12)
+#define SI470X_DE              __BIT16(11)
+#define SI470X_AGCD            __BIT16(10)
+#define SI470X_BLNDADJ         __BITS16(7, 6)
+#define SI470X_GPIO3           __BITS16(5, 4)
+#define SI470X_GPIO2           __BITS16(3, 2)
+#define SI470X_GPIO1           __BITS16(1, 0)
+
+#define SI470X_SYSCONFIG2      0x05
+#define SI470X_SEEKTH          __BITS16(15, 8)
+#define SI470X_BAND            __BITS16(7, 6)
+#define SI470X_SPACE           __BITS16(5, 4)
+#define SI470X_VOLUME          __BITS16(3, 0)
+
+#define SI470X_SYSCONFIG3      0x06
+#define SI470X_SMUTER          __BITS16(15, 14)
+#define SI470X_SMUTEA          __BITS16(13, 12)
+#define SI470X_VOLEXT          __BIT16(8)
+#define SI470X_SKSNR           __BITS16(7, 4)
+#define SI470X_SKCNT           __BITS16(3, 0)
+
+#define SI470X_TEST1           0x07
+#define SI470X_XOSCEN          __BIT16(15)
+#define SI470X_AHIZEN          __BIT16(14)
+
+#define SI470X_TEST2           0x08
+
+#define SI470X_BOOTCONFIG      0x09
+
+#define SI470X_STATUSRSSI      0x0a
+#define SI470X_RDSR            __BIT16(15)
+#define SI470X_STC             __BIT16(14)
+#define SI470X_SF_BL           __BIT16(13)
+#define SI470X_AFCRL           __BIT16(12)
+#define SI470X_RDSS            __BIT16(11)
+#define SI470X_BLERA           __BITS16(9, 10)
+#define SI470X_ST              __BIT16(8)
+#define SI470X_RSSI            __BITS16(7, 0)
+
+#define SI470X_READCHANNEL     0x0b
+#define SI470X_BLERB           __BITS16(15, 14)
+#define SI470X_BLERC           __BITS16(13, 12)
+#define SI470X_BLERD           __BITS16(11, 10)
+#define SI470X_READCHAN                __BITS16(9, 0)
+
+#define SI470X_RDSA            0x0c
+#define SI470X_RDSB            0x0d
+#define SI470X_RDSC            0x0e
+#define SI470X_RDSD            0x0f
+
+#endif /* _DEV_IC_SI470X_REG_H_ */
diff -r 96e982d091ed -r 5c1b6ca3032d sys/dev/usb/files.usb
--- a/sys/dev/usb/files.usb     Sun Jan 13 01:10:59 2013 +0000
+++ b/sys/dev/usb/files.usb     Sun Jan 13 01:15:02 2013 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.usb,v 1.126 2013/01/09 23:02:59 skrll Exp $
+#      $NetBSD: files.usb,v 1.127 2013/01/13 01:15:02 jakllsch Exp $
 #
 # Config file and device description for machine-independent USB code.
 # Included by ports that need it.  Ports that use it must provide
@@ -236,6 +236,11 @@
 attach udsbr at usbdevif
 file   dev/usb/udsbr.c                 udsbr
 
+# Silicon Labs USB radio module (FM)
+device slurm: radiodev
+attach slurm at usbifif
+file   dev/usb/slurm.c                 slurm
+
 # TEMPerHUM HID
 device uthum: hid, sysmon_envsys
 attach uthum at uhidbus
diff -r 96e982d091ed -r 5c1b6ca3032d sys/dev/usb/slurm.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/usb/slurm.c       Sun Jan 13 01:15:02 2013 +0000
@@ -0,0 +1,379 @@
+/*     $NetBSD: slurm.c,v 1.1 2013/01/13 01:15:02 jakllsch Exp $ */
+
+/*
+ * Copyright (c) 2012 Jonathan A. Kollasch
+ * 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: slurm.c,v 1.1 2013/01/13 01:15:02 jakllsch Exp $");
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
+#include <sys/conf.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
+#include <dev/usb/usbdi_util.h>
+#include <dev/usb/usbdevs.h>
+#include <dev/ic/si470x_reg.h>
+
+#include <sys/radioio.h>
+#include <dev/radio_if.h>
+
+#ifdef SLURM_DEBUG
+int    slurmdebug = 0;
+#define DPRINTFN(n, x) do { if (slurmdebug > (n)) printf x; } while (0)
+#else
+#define DPRINTFN(n, x)
+#endif
+
+#define DPRINTF(x) DPRINTFN(0, x)
+
+#define SI470X_VOLFACT (255 / __SHIFTOUT_MASK(SI470X_VOLUME))
+
+struct slurm_softc {
+       device_t                sc_dev;
+       usbd_device_handle      sc_udev;
+       usbd_interface_handle   sc_uif;
+       uint32_t                sc_band;
+       uint32_t                sc_space;
+};
+
+static const struct usb_devno slurm_devs[] = {
+       { USB_VENDOR_ADS, USB_PRODUCT_ADS_RDX155 },
+};
+
+static int slurm_match(device_t, cfdata_t, void *);
+static void slurm_attach(device_t, device_t, void *);
+static int slurm_detach(device_t, int);
+
+static int slurm_get_info(void *, struct radio_info *);
+static int slurm_set_info(void *, struct radio_info *);
+static int slurm_search(void *, int);
+
+static usbd_status slurm_setreg(struct slurm_softc *, int, uint16_t);
+static usbd_status slurm_getreg(struct slurm_softc *, int, uint16_t *);
+
+static uint32_t slurm_si470x_get_freq(struct slurm_softc *, uint16_t);
+static void slurm_si470x_get_bandspace(struct slurm_softc *, uint16_t);
+static int slurm_si470x_get_info(uint16_t);
+static int slurm_si470x_get_mute(uint16_t);
+static int slurm_si470x_get_stereo(uint16_t);
+static int slurm_si470x_get_volume(uint16_t);
+
+static int slurm_si470x_search(struct slurm_softc *, int);
+
+static void slurm_si470x_set_freq(struct slurm_softc *, uint32_t);
+static void slurm_si470x_set_powercfg(struct slurm_softc *, int, int);
+static void slurm_si470x_set_volume(struct slurm_softc *, int);
+
+static const struct radio_hw_if slurm_radio = {
+       .get_info = slurm_get_info,
+       .set_info = slurm_set_info,
+       .search = slurm_search,
+};
+
+CFATTACH_DECL_NEW(slurm, sizeof(struct slurm_softc),
+    slurm_match, slurm_attach, slurm_detach, NULL);
+
+static int 
+slurm_match(device_t parent, cfdata_t match, void *aux)
+{
+       const struct usbif_attach_arg * const uaa = aux;
+
+       if (uaa->ifaceno != 2)
+               return UMATCH_NONE;
+
+       if (usb_lookup(slurm_devs, uaa->vendor, uaa->product) != NULL) {
+               return UMATCH_VENDOR_PRODUCT;
+       }
+
+       return UMATCH_NONE;
+}
+
+static void 
+slurm_attach(device_t parent, device_t self, void *aux)
+{
+       struct slurm_softc * const sc = device_private(self);
+       const struct usbif_attach_arg * const uaa = aux;
+
+       sc->sc_dev = self;
+       sc->sc_udev = uaa->device;
+       sc->sc_uif = uaa->iface;
+
+       aprint_normal("\n");
+       aprint_naive("\n");
+
+       usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
+
+#ifdef SLURM_DEBUG
+       {
+               uint16_t val;
+               for (int i = 0; i < 16; i++) {
+                       slurm_getreg(sc, i, &val);
+                       device_printf(self, "%02x -> %04x\n", i, val);
+               }
+       }
+#endif
+
+       radio_attach_mi(&slurm_radio, sc, self);
+}
+
+static int 
+slurm_detach(device_t self, int flags)
+{
+       struct slurm_softc * const sc = device_private(self);
+       int rv = 0;
+
+       if ((rv = config_detach_children(self, flags)) != 0)
+               return rv;
+
+       usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
+           sc->sc_dev);



Home | Main Index | Thread Index | Old Index