mt2131.c revision 1.1 1 1.1 jakllsch /* $NetBSD: mt2131.c,v 1.1 2011/08/04 01:45:37 jakllsch Exp $ */
2 1.1 jakllsch
3 1.1 jakllsch /*
4 1.1 jakllsch * Copyright (c) 2008, 2011 Jonathan A. Kollasch
5 1.1 jakllsch * All rights reserved.
6 1.1 jakllsch *
7 1.1 jakllsch * Redistribution and use in source and binary forms, with or without
8 1.1 jakllsch * modification, are permitted provided that the following conditions
9 1.1 jakllsch * are met:
10 1.1 jakllsch * 1. Redistributions of source code must retain the above copyright
11 1.1 jakllsch * notice, this list of conditions and the following disclaimer.
12 1.1 jakllsch * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 jakllsch * notice, this list of conditions and the following disclaimer in the
14 1.1 jakllsch * documentation and/or other materials provided with the distribution.
15 1.1 jakllsch *
16 1.1 jakllsch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 1.1 jakllsch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.1 jakllsch * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.1 jakllsch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20 1.1 jakllsch * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 1.1 jakllsch * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 1.1 jakllsch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 1.1 jakllsch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 1.1 jakllsch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 1.1 jakllsch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 1.1 jakllsch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 1.1 jakllsch */
28 1.1 jakllsch
29 1.1 jakllsch #include <sys/cdefs.h>
30 1.1 jakllsch __KERNEL_RCSID(0, "$NetBSD: mt2131.c,v 1.1 2011/08/04 01:45:37 jakllsch Exp $");
31 1.1 jakllsch
32 1.1 jakllsch #include <sys/param.h>
33 1.1 jakllsch #include <sys/systm.h>
34 1.1 jakllsch #include <sys/device.h>
35 1.1 jakllsch #include <sys/kmem.h>
36 1.1 jakllsch #include <sys/syslog.h>
37 1.1 jakllsch #include <sys/proc.h>
38 1.1 jakllsch
39 1.1 jakllsch #include <dev/i2c/mt2131var.h>
40 1.1 jakllsch
41 1.1 jakllsch #define PWR 0x07
42 1.1 jakllsch #define UPC_1 0x0b
43 1.1 jakllsch #define AGC_RL 0x10
44 1.1 jakllsch #define MISC_2 0x15
45 1.1 jakllsch
46 1.1 jakllsch #define IF1 1220
47 1.1 jakllsch #define IF2 44000
48 1.1 jakllsch #define REF 16000
49 1.1 jakllsch
50 1.1 jakllsch static const uint8_t mt2131_initstring[] = {
51 1.1 jakllsch 0x01,
52 1.1 jakllsch 0x50, 0x00, 0x50, 0x80, 0x00, 0x49,
53 1.1 jakllsch 0xfa, 0x88, 0x08, 0x77, 0x41, 0x04, 0x00, 0x00, 0x00, 0x32,
54 1.1 jakllsch 0x7f, 0xda, 0x4c, 0x00, 0x10, 0xaa, 0x78, 0x80, 0xff, 0x68,
55 1.1 jakllsch 0xa0, 0xff, 0xdd, 0x00, 0x00
56 1.1 jakllsch };
57 1.1 jakllsch
58 1.1 jakllsch static const uint8_t mt2131_agcinitstring[] = {
59 1.1 jakllsch AGC_RL,
60 1.1 jakllsch 0x7f, 0xc8, 0x0a, 0x5f, 0x00, 0x04
61 1.1 jakllsch };
62 1.1 jakllsch
63 1.1 jakllsch
64 1.1 jakllsch struct mt2131_softc {
65 1.1 jakllsch device_t parent;
66 1.1 jakllsch i2c_tag_t tag;
67 1.1 jakllsch i2c_addr_t addr;
68 1.1 jakllsch uint32_t frequency;
69 1.1 jakllsch uint32_t bandwidth;
70 1.1 jakllsch };
71 1.1 jakllsch
72 1.1 jakllsch static int mt2131_init(struct mt2131_softc *);
73 1.1 jakllsch
74 1.1 jakllsch static int mt2131_read(struct mt2131_softc *, uint8_t, uint8_t *);
75 1.1 jakllsch static int mt2131_write(struct mt2131_softc *, uint8_t, uint8_t);
76 1.1 jakllsch
77 1.1 jakllsch struct mt2131_softc *
78 1.1 jakllsch mt2131_open(device_t parent, i2c_tag_t t, i2c_addr_t a)
79 1.1 jakllsch {
80 1.1 jakllsch struct mt2131_softc *sc;
81 1.1 jakllsch int ret;
82 1.1 jakllsch
83 1.1 jakllsch uint8_t cmd, reg;
84 1.1 jakllsch
85 1.1 jakllsch cmd = reg = 0;
86 1.1 jakllsch
87 1.1 jakllsch printf("%s\n", __func__);
88 1.1 jakllsch
89 1.1 jakllsch /* get id reg */
90 1.1 jakllsch iic_acquire_bus(t, I2C_F_POLL);
91 1.1 jakllsch ret = iic_exec(t, I2C_OP_READ_WITH_STOP, a, &cmd, 1, ®, 1, I2C_F_POLL);
92 1.1 jakllsch iic_release_bus(t, I2C_F_POLL);
93 1.1 jakllsch
94 1.1 jakllsch if (ret) {
95 1.1 jakllsch printf("%s read fail\n", __func__);
96 1.1 jakllsch return NULL;
97 1.1 jakllsch }
98 1.1 jakllsch
99 1.1 jakllsch printf("%s %02x\n", __func__, reg);
100 1.1 jakllsch
101 1.1 jakllsch if ((reg & 0xfe) != 0x3e)
102 1.1 jakllsch return NULL;
103 1.1 jakllsch
104 1.1 jakllsch sc = kmem_alloc(sizeof(*sc), KM_SLEEP);
105 1.1 jakllsch if (sc == NULL)
106 1.1 jakllsch return NULL;
107 1.1 jakllsch
108 1.1 jakllsch sc->parent = parent;
109 1.1 jakllsch sc->tag = t;
110 1.1 jakllsch sc->addr = a;
111 1.1 jakllsch
112 1.1 jakllsch mt2131_init(sc);
113 1.1 jakllsch
114 1.1 jakllsch return sc;
115 1.1 jakllsch }
116 1.1 jakllsch
117 1.1 jakllsch void
118 1.1 jakllsch mt2131_close(struct mt2131_softc *sc)
119 1.1 jakllsch {
120 1.1 jakllsch kmem_free(sc, sizeof(*sc));
121 1.1 jakllsch }
122 1.1 jakllsch
123 1.1 jakllsch int
124 1.1 jakllsch mt2131_tune_dtv(struct mt2131_softc *sc, const struct dvb_frontend_parameters *p)
125 1.1 jakllsch {
126 1.1 jakllsch int rv;
127 1.1 jakllsch uint64_t o1, o2;
128 1.1 jakllsch uint64_t d1, d2;
129 1.1 jakllsch uint32_t r1, r2;
130 1.1 jakllsch uint32_t fr;
131 1.1 jakllsch uint8_t b[7];
132 1.1 jakllsch uint8_t regval;
133 1.1 jakllsch
134 1.1 jakllsch mt2131_init(sc);
135 1.1 jakllsch
136 1.1 jakllsch b[0] = 0x01;
137 1.1 jakllsch
138 1.1 jakllsch if(p->frequency != 0 &&
139 1.1 jakllsch (p->frequency < 50000000 || p->frequency > 1000000000))
140 1.1 jakllsch return EINVAL;
141 1.1 jakllsch
142 1.1 jakllsch fr = p->frequency / 1000;
143 1.1 jakllsch
144 1.1 jakllsch o1 = fr + IF1 * 1000;
145 1.1 jakllsch o2 = o1 - fr - IF2;
146 1.1 jakllsch
147 1.1 jakllsch d1 = (o1 * 8192)/REF;
148 1.1 jakllsch d2 = (o2 * 8192)/REF;
149 1.1 jakllsch
150 1.1 jakllsch r1 = d1/8192;
151 1.1 jakllsch r2 = d2/8192;
152 1.1 jakllsch
153 1.1 jakllsch printf("mt2131 %lu %lu %lu %u\n", o1, d1, d1&0x1fff, r1);
154 1.1 jakllsch printf("mt2131 %lu %lu %lu %u\n", o2, d2, d2&0x1fff, r2);
155 1.1 jakllsch
156 1.1 jakllsch b[1] = (d1 & 0x1fe0) >> 5;
157 1.1 jakllsch b[2] = (d1 & 0x001f);
158 1.1 jakllsch b[3] = r1;
159 1.1 jakllsch b[4] = (d2 & 0x1fe0) >> 5;
160 1.1 jakllsch b[5] = (d2 & 0x001f);
161 1.1 jakllsch b[6] = r2;
162 1.1 jakllsch
163 1.1 jakllsch iic_acquire_bus(sc->tag, I2C_F_POLL);
164 1.1 jakllsch rv = iic_exec(sc->tag, I2C_OP_WRITE_WITH_STOP, sc->addr, b, 7, NULL, 0, I2C_F_POLL);
165 1.1 jakllsch iic_release_bus(sc->tag, I2C_F_POLL);
166 1.1 jakllsch
167 1.1 jakllsch regval = (fr - 27501) / 55000;
168 1.1 jakllsch
169 1.1 jakllsch if(regval > 0x13)
170 1.1 jakllsch regval = 0x13;
171 1.1 jakllsch
172 1.1 jakllsch printf("mt2131 %u\n", regval);
173 1.1 jakllsch
174 1.1 jakllsch rv = mt2131_write(sc, UPC_1, regval);
175 1.1 jakllsch
176 1.1 jakllsch if (rv != 0)
177 1.1 jakllsch printf("%s\n", __func__);
178 1.1 jakllsch
179 1.1 jakllsch sc->frequency = (o1 - o2 - IF2) * 1000;
180 1.1 jakllsch printf("%s freq %d\n", __func__, sc->frequency);
181 1.1 jakllsch
182 1.1 jakllsch int i;
183 1.1 jakllsch b[0] = 0x08;
184 1.1 jakllsch
185 1.1 jakllsch for ( i = 0; i < 100; i++) {
186 1.1 jakllsch rv = mt2131_read(sc, 0x08, ®val);
187 1.1 jakllsch
188 1.1 jakllsch if (( regval & 0x88 ) == 0x88 ) {
189 1.1 jakllsch printf("mt2131 - locked\n");
190 1.1 jakllsch break;
191 1.1 jakllsch } else {
192 1.1 jakllsch printf("mt2131 - not locked - %02x\n", b[1]);
193 1.1 jakllsch }
194 1.1 jakllsch kpause("mt2131", true, 1, NULL);
195 1.1 jakllsch }
196 1.1 jakllsch
197 1.1 jakllsch return rv;
198 1.1 jakllsch }
199 1.1 jakllsch
200 1.1 jakllsch static int
201 1.1 jakllsch mt2131_init(struct mt2131_softc *sc)
202 1.1 jakllsch {
203 1.1 jakllsch int ret;
204 1.1 jakllsch
205 1.1 jakllsch printf("%s\n", __func__);
206 1.1 jakllsch
207 1.1 jakllsch ret = iic_acquire_bus(sc->tag, I2C_F_POLL);
208 1.1 jakllsch if (ret)
209 1.1 jakllsch return -1;
210 1.1 jakllsch ret = iic_exec(sc->tag, I2C_OP_WRITE_WITH_STOP, sc->addr,
211 1.1 jakllsch mt2131_initstring, sizeof(mt2131_initstring), NULL, 0, I2C_F_POLL);
212 1.1 jakllsch if (ret)
213 1.1 jakllsch return -1;
214 1.1 jakllsch iic_release_bus(sc->tag, I2C_F_POLL);
215 1.1 jakllsch
216 1.1 jakllsch ret = mt2131_write(sc, UPC_1, 0x09);
217 1.1 jakllsch ret = mt2131_write(sc, MISC_2, 0x47);
218 1.1 jakllsch ret = mt2131_write(sc, PWR, 0xf2);
219 1.1 jakllsch ret = mt2131_write(sc, UPC_1, 0x01);
220 1.1 jakllsch
221 1.1 jakllsch ret = iic_acquire_bus(sc->tag, I2C_F_POLL);
222 1.1 jakllsch if (ret)
223 1.1 jakllsch return -1;
224 1.1 jakllsch ret = iic_exec(sc->tag, I2C_OP_WRITE_WITH_STOP, sc->addr,
225 1.1 jakllsch mt2131_agcinitstring, sizeof(mt2131_agcinitstring),
226 1.1 jakllsch NULL, 0, I2C_F_POLL);
227 1.1 jakllsch iic_release_bus(sc->tag, I2C_F_POLL);
228 1.1 jakllsch if (ret)
229 1.1 jakllsch return -1;
230 1.1 jakllsch
231 1.1 jakllsch return 0;
232 1.1 jakllsch }
233 1.1 jakllsch
234 1.1 jakllsch static int
235 1.1 jakllsch mt2131_read(struct mt2131_softc *sc, uint8_t r, uint8_t *v)
236 1.1 jakllsch {
237 1.1 jakllsch int ret;
238 1.1 jakllsch
239 1.1 jakllsch ret = iic_acquire_bus(sc->tag, I2C_F_POLL);
240 1.1 jakllsch if (ret)
241 1.1 jakllsch return ret;
242 1.1 jakllsch ret = iic_exec(sc->tag, I2C_OP_READ_WITH_STOP, sc->addr,
243 1.1 jakllsch &r, 1, v, 1, I2C_F_POLL);
244 1.1 jakllsch
245 1.1 jakllsch iic_release_bus(sc->tag, I2C_F_POLL);
246 1.1 jakllsch
247 1.1 jakllsch return ret;
248 1.1 jakllsch }
249 1.1 jakllsch
250 1.1 jakllsch static int
251 1.1 jakllsch mt2131_write(struct mt2131_softc *sc, uint8_t a, uint8_t v)
252 1.1 jakllsch {
253 1.1 jakllsch int ret;
254 1.1 jakllsch uint8_t b[] = { a, v };
255 1.1 jakllsch
256 1.1 jakllsch ret = iic_acquire_bus(sc->tag, I2C_F_POLL);
257 1.1 jakllsch if (ret)
258 1.1 jakllsch return ret;
259 1.1 jakllsch
260 1.1 jakllsch ret = iic_exec(sc->tag, I2C_OP_READ_WITH_STOP, sc->addr,
261 1.1 jakllsch b, sizeof(b), NULL, 0, I2C_F_POLL);
262 1.1 jakllsch
263 1.1 jakllsch iic_release_bus(sc->tag, I2C_F_POLL);
264 1.1 jakllsch
265 1.1 jakllsch return ret;
266 1.1 jakllsch }
267