BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / drivers / dvb / cx23882 / cx22702.c
blobecd9a082eafded884fef079618d1e8aca5515bf5
1 /*
2 * Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify,
8 * merge, publish, distribute, sublicense, and/or sell copies of
9 * the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
25 #include <KernelExport.h>
26 #include <string.h>
27 #include "cx22702.h"
28 #include "dtt7592.h"
29 #include "config.h"
30 #include "dvb.h"
32 #define TRACE_CX22702
33 #ifdef TRACE_CX22702
34 #define TRACE dprintf
35 #else
36 #define TRACE(a...)
37 #endif
40 #if 0
41 static void
42 cx22702_reg_dump(i2c_bus *bus)
44 int i;
45 for (i = 0; i < 256; i++) {
46 uint8 data;
47 if (cx22702_reg_read(bus, i, &data) != B_OK)
48 dprintf("cx22702_reg 0x%02x error\n", i);
49 else
50 dprintf("cx22702_reg 0x%02x value 0x%02x\n", i, data);
53 #endif
56 status_t
57 cx22702_reg_write(i2c_bus *bus, uint8 reg, uint8 data)
59 status_t res;
60 uint8 buf[2] = {reg, data};
61 res = i2c_write(bus, I2C_ADDR_DEMOD, buf, 2);
62 if (res != B_OK)
63 TRACE("cx22702_reg_write error, reg 0x%02x, value 0x%02x\n", reg, data);
64 return res;
68 status_t
69 cx22702_reg_read(i2c_bus *bus, uint8 reg, uint8 *data)
71 status_t res;
72 res = i2c_xfer(bus, I2C_ADDR_DEMOD, &reg, 1, data, 1);
73 if (res != B_OK)
74 TRACE("cx22702_reg_read error, reg 0x%02x\n", reg);
75 return res;
79 status_t
80 cx22702_init(i2c_bus *bus)
82 if (cx22702_reg_write(bus, 0x00, 0x02) != B_OK) return B_ERROR;
83 if (cx22702_reg_write(bus, 0x00, 0x00) != B_OK) return B_ERROR;
84 snooze(10000);
85 if (cx22702_reg_write(bus, 0x00, 0x00) != B_OK) return B_ERROR;
86 if (cx22702_reg_write(bus, 0x09, 0x01) != B_OK) return B_ERROR;
87 if (cx22702_reg_write(bus, 0x0B, 0x04) != B_OK) return B_ERROR;
88 if (cx22702_reg_write(bus, 0x0C, 0x00) != B_OK) return B_ERROR;
89 if (cx22702_reg_write(bus, 0x0D, 0x80) != B_OK) return B_ERROR;
90 if (cx22702_reg_write(bus, 0x26, 0x80) != B_OK) return B_ERROR;
91 if (cx22702_reg_write(bus, 0x2D, 0xff) != B_OK) return B_ERROR;
92 if (cx22702_reg_write(bus, 0xDC, 0x00) != B_OK) return B_ERROR;
93 if (cx22702_reg_write(bus, 0xE4, 0x00) != B_OK) return B_ERROR;
94 if (cx22702_reg_write(bus, 0xF8, 0x02) != B_OK) return B_ERROR;
95 if (cx22702_reg_write(bus, 0x00, 0x01) != B_OK) return B_ERROR;
96 return B_OK;
100 status_t
101 cx22702_get_frequency_info(i2c_bus *bus, dvb_frequency_info_t *info)
103 memset(info, 0, sizeof(*info));
104 info->frequency_min = 149000000;
105 info->frequency_max = 860000000;
106 info->frequency_step = 166667;
107 return B_OK;
111 status_t
112 cx22702_set_tuning_parameters(i2c_bus *bus, const dvb_t_tuning_parameters_t *params)
114 uint8 data;
115 status_t res;
117 if (cx22702_reg_write(bus, 0x00, 0x00) != B_OK)
118 return B_ERROR;
120 res = dtt7592_set_frequency(bus, params->frequency, params->bandwidth);
121 if (res != B_OK)
122 return res;
124 if (cx22702_reg_read(bus, 0x0c, &data) != B_OK)
125 return B_ERROR;
126 switch (params->inversion) {
127 case DVB_INVERSION_ON: data |= 0x01; break;
128 case DVB_INVERSION_OFF: data &= ~0x01; break;
129 default: return B_ERROR;
131 switch (params->bandwidth) {
132 case DVB_BANDWIDTH_6_MHZ: data = (data & ~0x10) | 0x20; break;
133 case DVB_BANDWIDTH_7_MHZ: data = (data & ~0x20) | 0x10; break;
134 case DVB_BANDWIDTH_8_MHZ: data &= ~0x30; break;
135 default: return B_ERROR;
137 if (cx22702_reg_write(bus, 0x0c, data) != B_OK)
138 return B_ERROR;
140 switch (params->modulation) {
141 case DVB_MODULATION_QPSK: data = 0x00; break;
142 case DVB_MODULATION_16_QAM: data = 0x08; break;
143 case DVB_MODULATION_64_QAM: data = 0x10; break;
144 default: return B_ERROR;
146 switch (params->hierarchy) {
147 case DVB_HIERARCHY_NONE: break;
148 case DVB_HIERARCHY_1: data |= 0x01; break;
149 case DVB_HIERARCHY_2: data |= 0x02; break;
150 case DVB_HIERARCHY_4: data |= 0x03; break;
151 default: return B_ERROR;
153 if (cx22702_reg_write(bus, 0x06, data) != B_OK)
154 return B_ERROR;
156 switch (params->code_rate_hp) {
157 case DVB_FEC_NONE: data = 0x00; break;
158 case DVB_FEC_1_2: data = 0x00; break;
159 case DVB_FEC_2_3: data = 0x08; break;
160 case DVB_FEC_3_4: data = 0x10; break;
161 case DVB_FEC_5_6: data = 0x18; break;
162 case DVB_FEC_6_7: data = 0x20; break;
163 default: return B_ERROR;
165 switch (params->code_rate_lp) {
166 case DVB_FEC_NONE: break;
167 case DVB_FEC_1_2: break;
168 case DVB_FEC_2_3: data |= 0x01; break;
169 case DVB_FEC_3_4: data |= 0x02; break;
170 case DVB_FEC_5_6: data |= 0x03; break;
171 case DVB_FEC_6_7: data |= 0x04; break;
172 default: return B_ERROR;
174 if (cx22702_reg_write(bus, 0x07, data) != B_OK)
175 return B_ERROR;
177 switch (params->transmission_mode) {
178 case DVB_TRANSMISSION_MODE_2K: data = 0x00; break;
179 case DVB_TRANSMISSION_MODE_8K: data = 0x01; break;
180 default: return B_ERROR;
182 switch (params->guard_interval) {
183 case DVB_GUARD_INTERVAL_1_4: data |= 0x0c; break;
184 case DVB_GUARD_INTERVAL_1_8: data |= 0x08; break;
185 case DVB_GUARD_INTERVAL_1_16: data |= 0x04; break;
186 case DVB_GUARD_INTERVAL_1_32: break;
187 default: return B_ERROR;
189 if (cx22702_reg_write(bus, 0x08, data) != B_OK)
190 return B_ERROR;
192 if (cx22702_reg_read(bus, 0x0b, &data) != B_OK)
193 return B_ERROR;
194 if (cx22702_reg_write(bus, 0x0b, data | 0x02) != B_OK)
195 return B_ERROR;
197 if (cx22702_reg_write(bus, 0x00, 0x01) != B_OK)
198 return B_ERROR;
200 // cx22702_reg_dump(bus);
202 return B_OK;
206 status_t
207 cx22702_get_tuning_parameters(i2c_bus *bus, dvb_t_tuning_parameters_t *params)
209 uint8 reg01, reg02, reg03, reg0A, reg0C;
211 if (cx22702_reg_read(bus, 0x01, &reg01) != B_OK)
212 return B_ERROR;
213 if (cx22702_reg_read(bus, 0x02, &reg02) != B_OK)
214 return B_ERROR;
215 if (cx22702_reg_read(bus, 0x03, &reg03) != B_OK)
216 return B_ERROR;
217 if (cx22702_reg_read(bus, 0x0a, &reg0A) != B_OK)
218 return B_ERROR;
219 if (cx22702_reg_read(bus, 0x0c, &reg0C) != B_OK)
220 return B_ERROR;
222 memset(params, 0, sizeof(*params));
223 params->inversion = (reg0C & 0x01) ? DVB_INVERSION_ON : DVB_INVERSION_OFF;
225 // XXX TODO...
227 return B_OK;
231 status_t
232 cx22702_get_status(i2c_bus *bus, dvb_status_t *status)
234 uint8 reg0A, reg23;
236 if (cx22702_reg_read(bus, 0x0a, &reg0A) != B_OK)
237 return B_ERROR;
238 if (cx22702_reg_read(bus, 0x23, &reg23) != B_OK)
239 return B_ERROR;
241 *status = 0;
242 if (reg0A & 0x10)
243 *status |= DVB_STATUS_LOCK | DVB_STATUS_VITERBI | DVB_STATUS_SYNC;
244 if (reg0A & 0x20)
245 *status |= DVB_STATUS_CARRIER;
246 if (reg23 < 0xf0)
247 *status |= DVB_STATUS_SIGNAL;
249 return B_OK;
253 status_t
254 cx22702_get_ss(i2c_bus *bus, uint32 *ss)
256 uint8 reg23;
257 if (cx22702_reg_read(bus, 0x23, &reg23) != B_OK)
258 return B_ERROR;
259 *ss = reg23;
260 return B_OK;
264 status_t
265 cx22702_get_ber(i2c_bus *bus, uint32 *ber)
267 uint8 regDE_1, regDE_2, regDF;
268 int trys;
270 trys = 50;
271 do {
272 if (cx22702_reg_read(bus, 0xDE, &regDE_1) != B_OK)
273 return B_ERROR;
274 if (cx22702_reg_read(bus, 0xDF, &regDF) != B_OK)
275 return B_ERROR;
276 if (cx22702_reg_read(bus, 0xDE, &regDE_2) != B_OK)
277 return B_ERROR;
278 } while (regDE_1 != regDE_2 && --trys > 0);
279 if (trys == 0)
280 return B_ERROR;
282 *ber = (regDE_1 & 0x7f) << 7 | (regDF & 0x7f);
284 return B_OK;
288 status_t
289 cx22702_get_snr(i2c_bus *bus, uint32 *snr)
291 uint32 ber;
292 status_t stat = cx22702_get_ber(bus, &ber);
293 *snr = 16384 - ber;
294 return stat;
298 status_t
299 cx22702_get_upc(i2c_bus *bus, uint32 *upc)
301 uint8 regE3;
303 if (cx22702_reg_read(bus, 0xE3, &regE3) != B_OK)
304 return B_ERROR;
305 if (cx22702_reg_write(bus, 0xE3, 0) != B_OK)
306 return B_ERROR;
307 *upc = regE3;
308 return B_OK;