1 1.3 christos /* $NetBSD: lm700x.c,v 1.3 2005/12/11 12:21:27 christos Exp $ */ 2 1.1 augustss /* $OpenBSD: lm700x.c,v 1.2 2001/12/06 16:28:18 mickey Exp $ */ 3 1.1 augustss 4 1.1 augustss /* 5 1.1 augustss * Copyright (c) 2001 Vladimir Popov <jumbo (at) narod.ru> 6 1.1 augustss * All rights reserved. 7 1.1 augustss * 8 1.1 augustss * Redistribution and use in source and binary forms, with or without 9 1.1 augustss * modification, are permitted provided that the following conditions 10 1.1 augustss * are met: 11 1.1 augustss * 1. Redistributions of source code must retain the above copyright 12 1.1 augustss * notice, this list of conditions and the following disclaimer. 13 1.1 augustss * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 augustss * notice, this list of conditions and the following disclaimer in the 15 1.1 augustss * documentation and/or other materials provided with the distribution. 16 1.1 augustss * 17 1.1 augustss * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 1.1 augustss * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 1.1 augustss * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 1.1 augustss * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 1.1 augustss * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 1.1 augustss * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 1.1 augustss * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 1.1 augustss * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 1.1 augustss * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 1.1 augustss * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 1.1 augustss */ 28 1.1 augustss 29 1.1 augustss /* Implementation of most common lm700x routines */ 30 1.1 augustss 31 1.1 augustss /* 32 1.1 augustss * Sanyo LM7001 Direct PLL Frequency Synthesizer 33 1.1 augustss * ??? See http://www.redsword.com/tjacobs/geeb/fmcard.htm 34 1.1 augustss * 35 1.1 augustss * The LM7001J and LM7001JM (used in Aztech/PackardBell cards) are PLL 36 1.1 augustss * frequency synthesizer LSIs for tuners. These LSIs are software compatible 37 1.1 augustss * with LM7000 (used in Radiotrack, Radioreveal RA300, some Mediaforte cards), 38 1.1 augustss * but do not include an IF calculation circuit. 39 1.1 augustss * 40 1.1 augustss * The FM VCO circuit includes a high-speed programmable divider that can 41 1.1 augustss * divide directly. 42 1.1 augustss * 43 1.1 augustss * Features: 44 1.1 augustss * Seven reference frequencies: 1, 5, 9, 10, 25, 50, and 100 kHz; 45 1.1 augustss * Band-switching outputs (3 bits); 46 1.1 augustss * Controller clock output (400 kHz); 47 1.1 augustss * Serial input circuit for data input (using the CE, CL and DATA pins). 48 1.1 augustss * 49 1.1 augustss * The LM7001J and LM7001JM have a 24-bit shift register. 50 1.1 augustss */ 51 1.2 lukem 52 1.2 lukem #include <sys/cdefs.h> 53 1.3 christos __KERNEL_RCSID(0, "$NetBSD: lm700x.c,v 1.3 2005/12/11 12:21:27 christos Exp $"); 54 1.1 augustss 55 1.1 augustss #include <sys/param.h> 56 1.1 augustss #include <sys/radioio.h> 57 1.1 augustss 58 1.1 augustss #include <dev/ic/lm700x.h> 59 1.1 augustss 60 1.1 augustss u_int32_t 61 1.1 augustss lm700x_encode_freq(u_int32_t nfreq, u_int32_t rf) 62 1.1 augustss { 63 1.1 augustss nfreq += IF_FREQ; 64 1.1 augustss nfreq /= lm700x_decode_ref(rf); 65 1.1 augustss return nfreq; 66 1.1 augustss } 67 1.1 augustss 68 1.1 augustss void 69 1.1 augustss lm700x_hardware_write(struct lm700x_t *lm, u_int32_t data, u_int32_t addon) 70 1.1 augustss { 71 1.1 augustss int i; 72 1.1 augustss 73 1.1 augustss lm->init(lm->iot, lm->ioh, lm->offset, lm->rsetdata | addon); 74 1.1 augustss 75 1.1 augustss for (i = 0; i < LM700X_REGISTER_LENGTH; i++) 76 1.1 augustss if (data & (1 << i)) { 77 1.1 augustss bus_space_write_1(lm->iot, lm->ioh, lm->offset, 78 1.1 augustss lm->wocl | addon); 79 1.1 augustss DELAY(LM700X_WRITE_DELAY); 80 1.1 augustss bus_space_write_1(lm->iot, lm->ioh, lm->offset, 81 1.1 augustss lm->woch | addon); 82 1.1 augustss DELAY(LM700X_WRITE_DELAY); 83 1.1 augustss bus_space_write_1(lm->iot, lm->ioh, lm->offset, 84 1.1 augustss lm->wocl | addon); 85 1.1 augustss } else { 86 1.1 augustss bus_space_write_1(lm->iot, lm->ioh, lm->offset, 87 1.1 augustss lm->wzcl | addon); 88 1.1 augustss DELAY(LM700X_WRITE_DELAY); 89 1.1 augustss bus_space_write_1(lm->iot, lm->ioh, lm->offset, 90 1.1 augustss lm->wzch | addon); 91 1.1 augustss DELAY(LM700X_WRITE_DELAY); 92 1.1 augustss bus_space_write_1(lm->iot, lm->ioh, lm->offset, 93 1.1 augustss lm->wzcl | addon); 94 1.1 augustss } 95 1.1 augustss 96 1.1 augustss lm->rset(lm->iot, lm->ioh, lm->offset, lm->rsetdata | addon); 97 1.1 augustss } 98 1.1 augustss 99 1.1 augustss u_int32_t 100 1.1 augustss lm700x_encode_ref(u_int8_t rf) 101 1.1 augustss { 102 1.1 augustss u_int32_t ret; 103 1.1 augustss 104 1.1 augustss if (rf < 36) 105 1.1 augustss ret = LM700X_REF_025; 106 1.1 augustss else if (rf > 35 && rf < 75) 107 1.1 augustss ret = LM700X_REF_050; 108 1.1 augustss else 109 1.1 augustss ret = LM700X_REF_100; 110 1.1 augustss 111 1.1 augustss return ret; 112 1.1 augustss } 113 1.1 augustss 114 1.1 augustss u_int8_t 115 1.1 augustss lm700x_decode_ref(u_int32_t rf) 116 1.1 augustss { 117 1.1 augustss u_int8_t ret; 118 1.1 augustss 119 1.1 augustss switch (rf) { 120 1.1 augustss case LM700X_REF_100: 121 1.1 augustss ret = 100; 122 1.1 augustss break; 123 1.1 augustss case LM700X_REF_025: 124 1.1 augustss ret = 25; 125 1.1 augustss break; 126 1.1 augustss case LM700X_REF_050: 127 1.1 augustss /* FALLTHROUGH */ 128 1.1 augustss default: 129 1.1 augustss ret = 50; 130 1.1 augustss break; 131 1.1 augustss } 132 1.1 augustss 133 1.1 augustss return ret; 134 1.1 augustss } 135