]> err.no Git - linux-2.6/blobdiff - drivers/media/radio/radio-gemtek.c
V4L/DVB (6319): radio-gemtek: fix 'VID_HARDWARE_GEMTEK' undeclared
[linux-2.6] / drivers / media / radio / radio-gemtek.c
index f959bb71c460b1081400625cc58a447872bc6b72..5e4b9ddb23c0a07e59998606acfe672f260e02df 100644 (file)
@@ -89,6 +89,14 @@ module_param(radio_nr, int, 0444);
 #define GEMTEK_LOWFREQ (87*16000)
 #define GEMTEK_HIGHFREQ        (108*16000)
 
+/*
+ * Frequency calculation constants.  Intermediate frequency 10.52 MHz (nominal
+ * value 10.7 MHz), reference divisor 6.39 kHz (nominal 6.25 kHz).
+ */
+#define FSCALE         8
+#define IF_OFFSET      ((unsigned int)(10.52 * 16000 * (1<<FSCALE)))
+#define REF_FREQ       ((unsigned int)(6.39 * 16 * (1<<FSCALE)))
+
 #define GEMTEK_CK              0x01    /* Clock signal                 */
 #define GEMTEK_DA              0x02    /* Serial data                  */
 #define GEMTEK_CE              0x04    /* Chip enable                  */
@@ -98,7 +106,6 @@ module_param(radio_nr, int, 0444);
 #define GEMTEK_PLL_OFF         0x07    /* PLL off                      */
 
 #define BU2614_BUS_SIZE        32      /* BU2614 / BU2614FS bus size           */
-#define BU2614_NOPS    8       /* Number of supported operations       */
 
 #define SHORT_DELAY 5          /* usec */
 #define LONG_DELAY 75          /* usec */
@@ -106,72 +113,53 @@ module_param(radio_nr, int, 0444);
 struct gemtek_device {
        unsigned long lastfreq;
        int muted;
-       unsigned long bu2614data[BU2614_NOPS];
-};
-
-enum {
-       BU2614_VOID,
-       BU2614_FREQ,    /* D0..D15, Frequency data                      */
-       BU2614_PORT,    /* P0..P2, Output port control data             */
-       BU2614_FMES,    /* CT, Frequency measurement beginning data     */
-       BU2614_STDF,    /* R0..R2, Standard frequency data              */
-       BU2614_SWIN,    /* S, Switch between FMIN / AMIN                */
-       BU2614_SWAL,    /* PS, Swallow counter division (AMIN only)     */
-       BU2614_FMUN,    /* GT, Frequency measurement time and unlock    */
-       BU2614_TEST     /* TS, Test data is input                       */
+       u32 bu2614data;
 };
 
-struct bu2614_op {
-       int op;         /* Operation */
-       int size;       /* Data size */
-};
+#define BU2614_FREQ_BITS       16 /* D0..D15, Frequency data           */
+#define BU2614_PORT_BITS       3 /* P0..P2, Output port control data   */
+#define BU2614_VOID_BITS       4 /* unused                             */
+#define BU2614_FMES_BITS       1 /* CT, Frequency measurement beginning data */
+#define BU2614_STDF_BITS       3 /* R0..R2, Standard frequency data    */
+#define BU2614_SWIN_BITS       1 /* S, Switch between FMIN / AMIN      */
+#define BU2614_SWAL_BITS        1 /* PS, Swallow counter division (AMIN only)*/
+#define BU2614_VOID2_BITS      1 /* unused                             */
+#define BU2614_FMUN_BITS       1 /* GT, Frequency measurement time & unlock */
+#define BU2614_TEST_BITS       1 /* TS, Test data is input             */
+
+#define BU2614_FREQ_SHIFT      0
+#define BU2614_PORT_SHIFT      (BU2614_FREQ_BITS + BU2614_FREQ_SHIFT)
+#define BU2614_VOID_SHIFT      (BU2614_PORT_BITS + BU2614_PORT_SHIFT)
+#define BU2614_FMES_SHIFT      (BU2614_VOID_BITS + BU2614_VOID_SHIFT)
+#define BU2614_STDF_SHIFT      (BU2614_FMES_BITS + BU2614_FMES_SHIFT)
+#define BU2614_SWIN_SHIFT      (BU2614_STDF_BITS + BU2614_STDF_SHIFT)
+#define BU2614_SWAL_SHIFT      (BU2614_SWIN_BITS + BU2614_SWIN_SHIFT)
+#define BU2614_VOID2_SHIFT     (BU2614_SWAL_BITS + BU2614_SWAL_SHIFT)
+#define BU2614_FMUN_SHIFT      (BU2614_VOID2_BITS + BU2614_VOID2_SHIFT)
+#define BU2614_TEST_SHIFT      (BU2614_FMUN_BITS + BU2614_FMUN_SHIFT)
+
+#define MKMASK(field)  (((1<<BU2614_##field##_BITS) - 1) << \
+                       BU2614_##field##_SHIFT)
+#define BU2614_PORT_MASK       MKMASK(PORT)
+#define BU2614_FREQ_MASK       MKMASK(FREQ)
+#define BU2614_VOID_MASK       MKMASK(VOID)
+#define BU2614_FMES_MASK       MKMASK(FMES)
+#define BU2614_STDF_MASK       MKMASK(STDF)
+#define BU2614_SWIN_MASK       MKMASK(SWIN)
+#define BU2614_SWAL_MASK       MKMASK(SWAL)
+#define BU2614_VOID2_MASK      MKMASK(VOID2)
+#define BU2614_FMUN_MASK       MKMASK(FMUN)
+#define BU2614_TEST_MASK       MKMASK(TEST)
 
 static struct gemtek_device gemtek_unit;
 
-static struct bu2614_op bu2614ops[] = {
-       {.op = BU2614_FREQ,
-        .size = 0x10},
-       {.op = BU2614_PORT,
-        .size = 0x03},
-       {.op = BU2614_VOID,
-        .size = 0x04},
-       {.op = BU2614_FMES,
-        .size = 0x01},
-       {.op = BU2614_STDF,
-        .size = 0x03},
-       {.op = BU2614_SWIN,
-        .size = 0x01},
-       {.op = BU2614_SWAL,
-        .size = 0x01},
-       {.op = BU2614_VOID,
-        .size = 0x01},
-       {.op = BU2614_FMUN,
-        .size = 0x01},
-       {.op = BU2614_TEST,
-        .size = 0x01}
-};
-
 static spinlock_t lock;
 
 /*
  * Set data which will be sent to BU2614FS.
  */
-static void gemtek_bu2614_set(struct gemtek_device *dev, int op,
-                             unsigned long data)
-{
-       int i, q;
-
-       for (i = 0, q = 0; q < ARRAY_SIZE(dev->bu2614data); ++i) {
-               if (bu2614ops[i].op == op) {
-                       dev->bu2614data[q] =
-                           data & ((1 << bu2614ops[i].size) - 1);
-                       return;
-               }
-
-               if (bu2614ops[i].op != BU2614_VOID)
-                       ++q;
-       }
-}
+#define gemtek_bu2614_set(dev, field, data) ((dev)->bu2614data = \
+       ((dev)->bu2614data & ~field##_MASK) | ((data) << field##_SHIFT))
 
 /*
  * Transmit settings to BU2614FS over GemTek IC.
@@ -189,25 +177,12 @@ static void gemtek_bu2614_transmit(struct gemtek_device *dev)
        outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, io);
        udelay(LONG_DELAY);
 
-       for (i = 0, q = 0; q < ARRAY_SIZE(dev->bu2614data); ++i) {
-               for (bit = 0; bit < bu2614ops[i].size; ++bit) {
-                       if (bu2614ops[i].op != BU2614_VOID &&
-                           dev->bu2614data[q] & (1 << bit)) {
-                               outb_p(mute | GEMTEK_CE | GEMTEK_DA, io);
-                               udelay(SHORT_DELAY);
-                               outb_p(mute | GEMTEK_CE | GEMTEK_DA |
-                                      GEMTEK_CK, io);
-                               udelay(SHORT_DELAY);
-                       } else {
-                               outb_p(mute | GEMTEK_CE, io);
-                               udelay(SHORT_DELAY);
-                               outb_p(mute | GEMTEK_CE | GEMTEK_CK, io);
-                               udelay(SHORT_DELAY);
-                       }
-               }
-
-               if (bu2614ops[i].op != BU2614_VOID)
-                       ++q;
+       for (i = 0, q = dev->bu2614data; i < 32; i++, q >>= 1) {
+           bit = (q & 1) ? GEMTEK_DA : 0;
+           outb_p(mute | GEMTEK_CE | bit, io);
+           udelay(SHORT_DELAY);
+           outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, io);
+           udelay(SHORT_DELAY);
        }
 
        outb_p(mute | GEMTEK_DA | GEMTEK_CK, io);
@@ -219,14 +194,11 @@ static void gemtek_bu2614_transmit(struct gemtek_device *dev)
 }
 
 /*
- * Convert FM-frequency for BU2614FS (3.125 KHz STDF expected).
+ * Calculate divisor from FM-frequency for BU2614FS (3.125 KHz STDF expected).
  */
-static inline void gemtek_convfreq(unsigned long *freq)
+static unsigned long gemtek_convfreq(unsigned long freq)
 {
-       (*freq) /= 160;
-       (*freq) += 1052;        /* FMIN, 10.52 MHz              */
-       (*freq) *= 1565;        /* STDF, 1 / 156.5 = 0.00639    */
-       (*freq) /= 1000;
+       return ((freq<<FSCALE) + IF_OFFSET + REF_FREQ/2) / REF_FREQ;
 }
 
 /*
@@ -253,10 +225,8 @@ static void gemtek_setfreq(struct gemtek_device *dev, unsigned long freq)
        gemtek_bu2614_set(dev, BU2614_FMUN, 1); /* GT bit set   */
        gemtek_bu2614_set(dev, BU2614_TEST, 0);
 
-       gemtek_convfreq(&freq);
-
        gemtek_bu2614_set(dev, BU2614_STDF, GEMTEK_STDF_3_125_KHZ);
-       gemtek_bu2614_set(dev, BU2614_FREQ, freq);
+       gemtek_bu2614_set(dev, BU2614_FREQ, gemtek_convfreq(freq));
 
        gemtek_bu2614_transmit(dev);
 }
@@ -584,7 +554,6 @@ static struct video_device gemtek_radio = {
        .owner                  = THIS_MODULE,
        .name                   = "GemTek Radio card",
        .type                   = VID_TYPE_TUNER,
-       .hardware               = VID_HARDWARE_GEMTEK,
        .fops                   = &gemtek_fops,
        .vidioc_querycap        = vidioc_querycap,
        .vidioc_g_tuner         = vidioc_g_tuner,
@@ -609,8 +578,6 @@ static struct video_device gemtek_radio = {
  */
 static int __init gemtek_init(void)
 {
-       int i;
-
        printk(KERN_INFO RADIO_BANNER "\n");
 
        spin_lock_init(&lock);
@@ -648,8 +615,7 @@ static int __init gemtek_init(void)
 
        /* Set defaults */
        gemtek_unit.lastfreq = GEMTEK_LOWFREQ;
-       for (i = 0; i < ARRAY_SIZE(gemtek_unit.bu2614data); ++i)
-               gemtek_unit.bu2614data[i] = 0;
+       gemtek_unit.bu2614data = 0;
 
        if (initmute)
                gemtek_mute(&gemtek_unit);