2 * Copyright (c) 2003, 2004, 2005
3 * John Wehle <john@feith.com>. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by John Wehle.
16 * 4. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * EEPROM routines for the Conexant MPEG-2 Codec driver.
35 * Ideally these routines should be implemented as a separate
36 * driver which has a generic EEPROM interface so that it's
37 * not necessary for each multimedia driver to re-invent the
42 #include <sys/param.h>
43 #include <sys/systm.h>
46 #include <sys/kernel.h>
48 #include <sys/select.h>
49 #include <sys/resource.h>
54 #include <machine/clock.h>
56 #include <dev/video/cxm/cxm.h>
58 #include <bus/iicbus/iiconf.h>
59 #include <bus/iicbus/iicbus.h>
65 cxm_eeprom_read(device_t iicbus, int i2c_addr,
66 char *buf, int len, unsigned int offset)
72 msg[0] = (unsigned char)offset;
74 if (iicbus_start(iicbus, i2c_addr, CXM_I2C_TIMEOUT) != 0)
77 if (iicbus_write(iicbus, msg, sizeof(msg), &sent, CXM_I2C_TIMEOUT) != 0
78 || sent != sizeof(msg))
81 if (iicbus_repeated_start(iicbus, i2c_addr + 1, CXM_I2C_TIMEOUT) != 0)
84 if (iicbus_read(iicbus, buf, len, &received, IIC_LAST_READ, 0) != 0)
98 cxm_eeprom_init(struct cxm_softc *sc)
100 unsigned char eeprom[1];
102 if (cxm_eeprom_read(sc->iicbus, CXM_I2C_EEPROM,
103 eeprom, sizeof(eeprom), 0) != sizeof(eeprom))
111 cxm_eeprom_tuner_type(struct cxm_softc *sc)
113 unsigned char eeprom[256];
116 unsigned int subsystem_vendor_id;
117 unsigned int tuner_code;
120 if (cxm_eeprom_read(sc->iicbus, CXM_I2C_EEPROM,
121 eeprom, sizeof(eeprom), 0) != sizeof(eeprom))
124 subsystem_vendor_id = (unsigned int)eeprom[254] << 8 | eeprom[255];
127 switch (subsystem_vendor_id) {
128 case PCI_VENDOR_HAUPPAUGE:
131 * The Hauppauge eeprom format is tagged.
134 if (eeprom[0] != 0x84) {
135 device_printf(sc->dev,
136 "unknown Hauppauge eeprom format %#x\n",
137 (unsigned int)eeprom[0]);
143 for (i = 0; i < sizeof(eeprom); i += len) {
145 if (eeprom[i] == 0x84) {
146 len = (unsigned int)eeprom[i + 2] << 8
149 } else if ((eeprom[i] & 0xf0) == 0x70) {
150 if (eeprom[i] & 0x08)
152 len = eeprom[i] & 0x07;
155 device_printf(sc->dev,
156 "unknown Hauppauge eeprom packet %#x\n",
157 (unsigned int)eeprom[i]);
161 if (i >= sizeof(eeprom)
162 || (i + len) > sizeof(eeprom)) {
163 device_printf(sc->dev,
164 "corrupt Hauppauge eeprom packet\n");
170 tuner_code = eeprom[i + 6];
174 tuner_code = eeprom[i + 2];
182 switch (tuner_code) {
183 case 0x03: /* Philips FI1216 */
184 case 0x08: /* Philips FI1216 MK2 */
185 tuner_type = CXM_TUNER_PHILIPS_FI1216_MK2;
188 case 0x22: /* Philips FQ1216ME */
189 tuner_type = CXM_TUNER_PHILIPS_FQ1216ME;
192 case 0x37: /* Philips FQ1216ME MK3 */
193 tuner_type = CXM_TUNER_PHILIPS_FQ1216ME_MK3;
196 case 0x1d: /* Temic 4006FH5 */
197 tuner_type = CXM_TUNER_TEMIC_4006_FH5;
200 case 0x30: /* LG Innotek TPI8PSB11D */
201 tuner_type = CXM_TUNER_LG_TPI8PSB11D;
204 case 0x34: /* Microtune 4049FM5 */
205 tuner_type = CXM_TUNER_MICROTUNE_4049_FM5;
208 case 0x05: /* Philips FI1236 */
209 case 0x0a: /* Philips FI1236 MK2 */
210 tuner_type = CXM_TUNER_PHILIPS_FI1236_MK2;
213 case 0x1a: /* Temic 4036FY5 */
214 tuner_type = CXM_TUNER_TEMIC_4036_FY5;
217 case 0x52: /* LG Innotek TAPC-H701F */
218 tuner_type = CXM_TUNER_LG_TAPC_H701F;
221 case 0x55: /* TCL 2002N-6A */
222 tuner_type = CXM_TUNER_TCL_2002N_6A;
225 case 0x06: /* Philips FI1246 */
226 case 0x0b: /* Philips FI1246 MK2 */
227 tuner_type = CXM_TUNER_PHILIPS_FI1246_MK2;
230 case 0x23: /* Temic 4066FY5 */
231 tuner_type = CXM_TUNER_TEMIC_4066_FY5;
234 case 0x10: /* Philips FR1216 MK2 */
235 case 0x15: /* Philips FM1216 */
236 tuner_type = CXM_TUNER_PHILIPS_FM1216;
239 case 0x39: /* Philips FM1216ME MK3 */
240 tuner_type = CXM_TUNER_PHILIPS_FM1216ME_MK3;
243 case 0x2a: /* Temic 4009FR5 */
244 tuner_type = CXM_TUNER_TEMIC_4009_FR5;
247 case 0x2f: /* LG Innotek TPI8PSB01N */
248 tuner_type = CXM_TUNER_LG_TPI8PSB01N;
251 case 0x12: /* Philips FR1236 MK2 */
252 case 0x17: /* Philips FM1236 */
253 tuner_type = CXM_TUNER_PHILIPS_FM1236;
256 case 0x21: /* Temic 4039FR5 */
257 tuner_type = CXM_TUNER_TEMIC_4039_FR5;
260 case 0x44: /* LG Innotek TAPE-H001F */
261 tuner_type = CXM_TUNER_LG_TAPE_H001F;
264 case 0x13: /* Philips FR1246 MK2 */
265 case 0x18: /* Philips FM1246 */
266 tuner_type = CXM_TUNER_PHILIPS_FM1246;
270 device_printf(sc->dev, "unknown tuner code %#x\n",
277 device_printf(sc->dev, "unknown subsystem vendor id %#x\n",
278 subsystem_vendor_id);