summaryrefslogtreecommitdiff
path: root/sys/dev/ic/lm700x.c
blob: e622b67ba52cfeaee3dd96749c4754da6463b3dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*	$OpenBSD: lm700x.c,v 1.2 2001/12/06 16:28:18 mickey Exp $	*/

/*
 * Copyright (c) 2001 Vladimir Popov <jumbo@narod.ru>
 * 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 ``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 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.
 */

/* Implementation of most common lm700x routines */

/*
 * Sanyo LM7001 Direct PLL Frequency Synthesizer
 *    ??? See http://www.redsword.com/tjacobs/geeb/fmcard.htm
 *
 * The LM7001J and LM7001JM (used in Aztech/PackardBell cards) are PLL
 * frequency synthesizer LSIs for tuners. These LSIs are software compatible
 * with LM7000 (used in Radiotrack, Radioreveal RA300, some Mediaforte cards),
 * but do not include an IF calculation circuit.
 *
 * The FM VCO circuit includes a high-speed programmable divider that can
 * divide directly.
 *
 * Features:
 * Seven reference frequencies: 1, 5, 9, 10, 25, 50, and 100 kHz;
 * Band-switching outputs (3 bits);
 * Controller clock output (400 kHz);
 * Serial input circuit for data input (using the CE, CL and DATA pins).
 *
 * The LM7001J and LM7001JM have a 24-bit shift register.
 */

#include <sys/param.h>
#include <sys/radioio.h>

#include <dev/ic/lm700x.h>

u_int32_t
lm700x_encode_freq(u_int32_t nfreq, u_int32_t rf)
{
	nfreq += IF_FREQ;
	nfreq /= lm700x_decode_ref(rf);
	return nfreq;
}

void
lm700x_hardware_write(struct lm700x_t *lm, u_int32_t data, u_int32_t addon)
{
	int i;

	lm->init(lm->iot, lm->ioh, lm->offset, lm->rsetdata | addon);

	for (i = 0; i < LM700X_REGISTER_LENGTH; i++)
		if (data & (1 << i)) {
			bus_space_write_1(lm->iot, lm->ioh, lm->offset,
					lm->wocl | addon);
			DELAY(LM700X_WRITE_DELAY);
			bus_space_write_1(lm->iot, lm->ioh, lm->offset,
					lm->woch | addon);
			DELAY(LM700X_WRITE_DELAY);
			bus_space_write_1(lm->iot, lm->ioh, lm->offset,
					lm->wocl | addon);
		} else {
			bus_space_write_1(lm->iot, lm->ioh, lm->offset,
					lm->wzcl | addon);
			DELAY(LM700X_WRITE_DELAY);
			bus_space_write_1(lm->iot, lm->ioh, lm->offset,
					lm->wzch | addon);
			DELAY(LM700X_WRITE_DELAY);
			bus_space_write_1(lm->iot, lm->ioh, lm->offset,
					lm->wzcl | addon);
		}

	lm->rset(lm->iot, lm->ioh, lm->offset, lm->rsetdata | addon);
}

u_int32_t
lm700x_encode_ref(u_int8_t rf)
{
	u_int32_t ret;

	if (rf < 36)
		ret = LM700X_REF_025;
	else if (rf > 35 && rf < 75)
			ret = LM700X_REF_050;
	else
		ret = LM700X_REF_100;

	return ret;
}

u_int8_t
lm700x_decode_ref(u_int32_t rf)
{
	u_int8_t ret;

	switch (rf) {
	case LM700X_REF_100:
		ret = 100;
		break;
	case LM700X_REF_025:
		ret = 25;
		break;
	case LM700X_REF_050:
		/* FALLTHROUGH */
	default:
		ret = 50;
		break;
	}

	return ret;
}