bktr_tuner.c (131180) | bktr_tuner.c (138936) |
---|---|
1/*- 2 * 1. Redistributions of source code must retain the 3 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 18 unchanged lines hidden (view full) --- 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34#include <sys/cdefs.h> | 1/*- 2 * 1. Redistributions of source code must retain the 3 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 18 unchanged lines hidden (view full) --- 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34#include <sys/cdefs.h> |
35__FBSDID("$FreeBSD: head/sys/dev/bktr/bktr_tuner.c 131180 2004-06-27 09:59:02Z schweikh $"); | 35__FBSDID("$FreeBSD: head/sys/dev/bktr/bktr_tuner.c 138936 2004-12-16 23:37:41Z julian $"); |
36 37/* 38 * This is part of the Driver for Video Capture Cards (Frame grabbers) 39 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 40 * chipset. 41 * Copyright Roger Hardiman and Amancio Hasty. 42 * 43 * bktr_tuner : This deals with controlling the tuner fitted to TV cards. --- 87 unchanged lines hidden (view full) --- 131/* The control value for the ALPS TSCH5 Tuner */ 132#define TSCH5_FCONTROL 0x82 133#define TSCH5_RADIO 0x86 134 135/* The control value for the ALPS TSBH1 Tuner */ 136#define TSBH1_FCONTROL 0xce 137 138 | 36 37/* 38 * This is part of the Driver for Video Capture Cards (Frame grabbers) 39 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 40 * chipset. 41 * Copyright Roger Hardiman and Amancio Hasty. 42 * 43 * bktr_tuner : This deals with controlling the tuner fitted to TV cards. --- 87 unchanged lines hidden (view full) --- 131/* The control value for the ALPS TSCH5 Tuner */ 132#define TSCH5_FCONTROL 0x82 133#define TSCH5_RADIO 0x86 134 135/* The control value for the ALPS TSBH1 Tuner */ 136#define TSBH1_FCONTROL 0xce 137 138 |
139static void mt2032_set_tv_freq(bktr_ptr_t bktr, unsigned int freq); 140static int mt2032_init(bktr_ptr_t bktr); 141 142 |
|
139static const struct TUNER tuners[] = { 140/* XXX FIXME: fill in the band-switch crosspoints */ 141 /* NO_TUNER */ 142 { "<no>", /* the 'name' */ 143 TTYPE_XXX, /* input type */ 144 { 0x00, /* control byte for Tuner PLL */ 145 0x00, 146 0x00, --- 124 unchanged lines hidden (view full) --- 271 /* ALPS TSBH1 NTSC */ 272 { "ALPS TSBH1 NTSC", /* the 'name' */ 273 TTYPE_NTSC, /* input type */ 274 { TSBH1_FCONTROL, /* control byte for Tuner PLL */ 275 TSBH1_FCONTROL, 276 TSBH1_FCONTROL, 277 0x00 }, 278 { 0x00, 0x00 }, /* band-switch crosspoints */ | 143static const struct TUNER tuners[] = { 144/* XXX FIXME: fill in the band-switch crosspoints */ 145 /* NO_TUNER */ 146 { "<no>", /* the 'name' */ 147 TTYPE_XXX, /* input type */ 148 { 0x00, /* control byte for Tuner PLL */ 149 0x00, 150 0x00, --- 124 unchanged lines hidden (view full) --- 275 /* ALPS TSBH1 NTSC */ 276 { "ALPS TSBH1 NTSC", /* the 'name' */ 277 TTYPE_NTSC, /* input type */ 278 { TSBH1_FCONTROL, /* control byte for Tuner PLL */ 279 TSBH1_FCONTROL, 280 TSBH1_FCONTROL, 281 0x00 }, 282 { 0x00, 0x00 }, /* band-switch crosspoints */ |
279 { 0x01, 0x02, 0x08, 0x00 } } /* the band-switch values */ | 283 { 0x01, 0x02, 0x08, 0x00 } }, /* the band-switch values */ 284 285 /* MT2032 Microtune */ 286 { "MT2032", /* the 'name' */ 287 TTYPE_PAL, /* input type */ 288 { TSA552x_SCONTROL, /* control byte for Tuner PLL */ 289 TSA552x_SCONTROL, 290 TSA552x_SCONTROL, 291 0x00 }, 292 { 0x00, 0x00 }, /* band-switch crosspoints */ 293 { 0xa0, 0x90, 0x30, 0x00 } }, /* the band-switch values */ |
280}; 281 282 283/* scaling factor for frequencies expressed as ints */ 284#define FREQFACTOR 16 285 286/* 287 * Format: --- 419 unchanged lines hidden (view full) --- 707/* This is needed as the tuner details are no longer globally declared */ 708 709void select_tuner( bktr_ptr_t bktr, int tuner_type ) { 710 if (tuner_type < Bt848_MAX_TUNER) { 711 bktr->card.tuner = &tuners[ tuner_type ]; 712 } else { 713 bktr->card.tuner = NULL; 714 } | 294}; 295 296 297/* scaling factor for frequencies expressed as ints */ 298#define FREQFACTOR 16 299 300/* 301 * Format: --- 419 unchanged lines hidden (view full) --- 721/* This is needed as the tuner details are no longer globally declared */ 722 723void select_tuner( bktr_ptr_t bktr, int tuner_type ) { 724 if (tuner_type < Bt848_MAX_TUNER) { 725 bktr->card.tuner = &tuners[ tuner_type ]; 726 } else { 727 bktr->card.tuner = NULL; 728 } |
729 if (tuner_type == TUNER_MT2032) { 730 mt2032_init(bktr); 731 } |
|
715} 716 717/* 718 * Tuner Notes: 719 * Programming the tuner properly is quite complicated. 720 * Here are some notes, based on a FM1246 data sheet for a PAL-I tuner. 721 * The tuner (front end) covers 45.75 Mhz - 855.25 Mhz and an FM band of 722 * 87.5 Mhz to 108.0 Mhz. --- 61 unchanged lines hidden (view full) --- 784#if defined( TEST_TUNER_AFC ) 785 int oldFrequency, afcDelta; 786#endif 787 788 tuner = bktr->card.tuner; 789 if ( tuner == NULL ) 790 return( -1 ); 791 | 732} 733 734/* 735 * Tuner Notes: 736 * Programming the tuner properly is quite complicated. 737 * Here are some notes, based on a FM1246 data sheet for a PAL-I tuner. 738 * The tuner (front end) covers 45.75 Mhz - 855.25 Mhz and an FM band of 739 * 87.5 Mhz to 108.0 Mhz. --- 61 unchanged lines hidden (view full) --- 801#if defined( TEST_TUNER_AFC ) 802 int oldFrequency, afcDelta; 803#endif 804 805 tuner = bktr->card.tuner; 806 if ( tuner == NULL ) 807 return( -1 ); 808 |
809 if (tuner == &tuners[TUNER_MT2032]) { 810 mt2032_set_tv_freq(bktr, frequency); 811 return 0; 812 } |
|
792 if (type == TV_FREQUENCY) { 793 /* 794 * select the band based on frequency 795 * XXX FIXME: get the cross-over points from the tuner struct 796 */ 797 if ( frequency < (160 * FREQFACTOR ) ) 798 band_select = LOW_BAND; 799 else if ( frequency < (454 * FREQFACTOR ) ) --- 171 unchanged lines hidden (view full) --- 971#endif /* TUNER_AFC */ 972#undef TBL_IF 973 974 975/* 976 * Get the Tuner status and signal strength 977 */ 978int get_tuner_status( bktr_ptr_t bktr ) { | 813 if (type == TV_FREQUENCY) { 814 /* 815 * select the band based on frequency 816 * XXX FIXME: get the cross-over points from the tuner struct 817 */ 818 if ( frequency < (160 * FREQFACTOR ) ) 819 band_select = LOW_BAND; 820 else if ( frequency < (454 * FREQFACTOR ) ) --- 171 unchanged lines hidden (view full) --- 992#endif /* TUNER_AFC */ 993#undef TBL_IF 994 995 996/* 997 * Get the Tuner status and signal strength 998 */ 999int get_tuner_status( bktr_ptr_t bktr ) { |
1000 if (bktr->card.tuner == &tuners[TUNER_MT2032]) 1001 return 0; |
|
979 return i2cRead( bktr, bktr->card.tuner_pllAddr + 1 ); 980} 981 982/* 983 * set the channel of the tuner 984 */ 985int 986tv_channel( bktr_ptr_t bktr, int channel ) --- 23 unchanged lines hidden (view full) --- 1010 return( EINVAL ); 1011 1012 memcpy(&chnlset->name, &freqTable[chnlset->index].name, 1013 BT848_MAX_CHNLSET_NAME_LEN); 1014 1015 chnlset->max_channel=freqTable[chnlset->index].ptr[0]; 1016 return( 0 ); 1017} | 1002 return i2cRead( bktr, bktr->card.tuner_pllAddr + 1 ); 1003} 1004 1005/* 1006 * set the channel of the tuner 1007 */ 1008int 1009tv_channel( bktr_ptr_t bktr, int channel ) --- 23 unchanged lines hidden (view full) --- 1033 return( EINVAL ); 1034 1035 memcpy(&chnlset->name, &freqTable[chnlset->index].name, 1036 BT848_MAX_CHNLSET_NAME_LEN); 1037 1038 chnlset->max_channel=freqTable[chnlset->index].ptr[0]; 1039 return( 0 ); 1040} |
1041 1042 1043 1044 1045#define TDA9887_ADDR 0x86 1046 1047int 1048TDA9887_init(bktr_ptr_t bktr, int output2_enable) 1049{ 1050 u_char addr = TDA9887_ADDR; 1051#if 0 1052 char buf[8]; 1053 1054 /* NOTE: these are PAL values */ 1055 buf[0] = 0; /* sub address */ 1056 buf[1] = 0x50; /* output port1 inactive */ 1057 buf[2] = 0x6e; /* tuner takeover point / de-emphasis */ 1058 buf[3] = 0x09; /* fVIF = 38.9 MHz, fFM = 5.5 MHz */ 1059 1060 if (!output2_enable) 1061 buf[1] |= 0x80; 1062 1063 if (i2cWriteBuf(bktr, addr, 4, buf) == -1) { 1064 printf("%s: TDA9887 write failed\n", bktr_name(bktr)); 1065 return -1; 1066 } 1067#else 1068 i2cWrite(bktr, addr, 0, output2_enable ? 0x50 : 0xd0); 1069 i2cWrite(bktr, addr, 1, 0x6e); 1070 i2cWrite(bktr, addr, 2, 0x09); 1071#endif 1072 return 0; 1073} 1074 1075 1076 1077#define MT2032_OPTIMIZE_VCO 1 1078 1079/* holds the value of XOGC register after init */ 1080static int MT2032_XOGC = 4; 1081 1082/* card.tuner_pllAddr not set during init */ 1083#define MT2032_ADDR 0xc0 1084 1085#ifndef MT2032_ADDR 1086#define MT2032_ADDR (bktr->card.tuner_pllAddr) 1087#endif 1088 1089static u_char 1090_MT2032_GetRegister(bktr_ptr_t bktr, u_char regNum) 1091{ 1092 int ch; 1093 1094 if (i2cWrite(bktr, MT2032_ADDR, regNum, -1) == -1) { 1095 printf("%s: MT2032 write failed (i2c addr %#x)\n", 1096 bktr_name(bktr), MT2032_ADDR); 1097 } 1098 if ((ch = i2cRead(bktr, MT2032_ADDR + 1)) == -1) { 1099 printf("%s: MT2032 get register %d failed\n", 1100 bktr_name(bktr), regNum); 1101 return 0; 1102 } 1103 return ch; 1104} 1105 1106static void 1107_MT2032_SetRegister(bktr_ptr_t bktr, u_char regNum, u_char data) 1108{ 1109 i2cWrite(bktr, MT2032_ADDR, regNum, data); 1110} 1111 1112#define MT2032_GetRegister(r) _MT2032_GetRegister(bktr,r) 1113#define MT2032_SetRegister(r,d) _MT2032_SetRegister(bktr,r,d) 1114 1115 1116static int 1117mt2032_init(bktr_ptr_t bktr) 1118{ 1119 u_char rdbuf[22]; 1120 int xogc, xok = 0; 1121 int i; 1122 1123 TDA9887_init(bktr, 0); 1124 1125 for (i = 0; i < 21; i++) 1126 rdbuf[i] = MT2032_GetRegister(i); 1127 1128 printf("%s: MT2032: Companycode=%02x%02x Part=%02x Revision=%02x\n", 1129 bktr_name(bktr), 1130 rdbuf[0x11], rdbuf[0x12], rdbuf[0x13], rdbuf[0x14]); 1131 1132 /* Initialize Registers per spec. */ 1133 MT2032_SetRegister(2, 0xff); 1134 MT2032_SetRegister(3, 0x0f); 1135 MT2032_SetRegister(4, 0x1f); 1136 MT2032_SetRegister(6, 0xe4); 1137 MT2032_SetRegister(7, 0x8f); 1138 MT2032_SetRegister(8, 0xc3); 1139 MT2032_SetRegister(9, 0x4e); 1140 MT2032_SetRegister(10, 0xec); 1141 MT2032_SetRegister(13, 0x32); 1142 1143 /* Adjust XOGC (register 7), wait for XOK */ 1144 xogc = 7; 1145 do { 1146 DELAY(10000); 1147 xok = MT2032_GetRegister(0x0e) & 0x01; 1148 if (xok == 1) { 1149 break; 1150 } 1151 xogc--; 1152 if (xogc == 3) { 1153 xogc = 4; /* min. 4 per spec */ 1154 break; 1155 } 1156 MT2032_SetRegister(7, 0x88 + xogc); 1157 } while (xok != 1); 1158 1159 TDA9887_init(bktr, 1); 1160 1161 MT2032_XOGC = xogc; 1162 1163 return 0; 1164} 1165 1166static int 1167MT2032_SpurCheck(int f1, int f2, int spectrum_from, int spectrum_to) 1168{ 1169 int n1 = 1, n2, f; 1170 1171 f1 = f1 / 1000; /* scale to kHz to avoid 32bit overflows */ 1172 f2 = f2 / 1000; 1173 spectrum_from /= 1000; 1174 spectrum_to /= 1000; 1175 1176 do { 1177 n2 = -n1; 1178 f = n1 * (f1 - f2); 1179 do { 1180 n2--; 1181 f = f - f2; 1182 if ((f > spectrum_from) && (f < spectrum_to)) { 1183 return 1; 1184 } 1185 } while ((f > (f2 - spectrum_to)) || (n2 > -5)); 1186 n1++; 1187 } while (n1 < 5); 1188 1189 return 0; 1190} 1191 1192static int 1193MT2032_ComputeFreq( 1194 int rfin, 1195 int if1, 1196 int if2, 1197 int spectrum_from, 1198 int spectrum_to, 1199 unsigned char *buf, 1200 int *ret_sel, 1201 int xogc 1202) 1203{ /* all in Hz */ 1204 int fref, lo1, lo1n, lo1a, s, sel; 1205 int lo1freq, desired_lo1, desired_lo2, lo2, lo2n, lo2a, 1206 lo2num, lo2freq; 1207 int nLO1adjust; 1208 1209 fref = 5250 * 1000; /* 5.25MHz */ 1210 1211 /* per spec 2.3.1 */ 1212 desired_lo1 = rfin + if1; 1213 lo1 = (2 * (desired_lo1 / 1000) + (fref / 1000)) / (2 * fref / 1000); 1214 lo1freq = lo1 * fref; 1215 desired_lo2 = lo1freq - rfin - if2; 1216 1217 /* per spec 2.3.2 */ 1218 for (nLO1adjust = 1; nLO1adjust < 3; nLO1adjust++) { 1219 if (!MT2032_SpurCheck(lo1freq, desired_lo2, spectrum_from, spectrum_to)) { 1220 break; 1221 } 1222 if (lo1freq < desired_lo1) { 1223 lo1 += nLO1adjust; 1224 } else { 1225 lo1 -= nLO1adjust; 1226 } 1227 1228 lo1freq = lo1 * fref; 1229 desired_lo2 = lo1freq - rfin - if2; 1230 } 1231 1232 /* per spec 2.3.3 */ 1233 s = lo1freq / 1000 / 1000; 1234 1235 if (MT2032_OPTIMIZE_VCO) { 1236 if (s > 1890) { 1237 sel = 0; 1238 } else if (s > 1720) { 1239 sel = 1; 1240 } else if (s > 1530) { 1241 sel = 2; 1242 } else if (s > 1370) { 1243 sel = 3; 1244 } else { 1245 sel = 4;/* >1090 */ 1246 } 1247 } else { 1248 if (s > 1790) { 1249 sel = 0;/* <1958 */ 1250 } else if (s > 1617) { 1251 sel = 1; 1252 } else if (s > 1449) { 1253 sel = 2; 1254 } else if (s > 1291) { 1255 sel = 3; 1256 } else { 1257 sel = 4;/* >1090 */ 1258 } 1259 } 1260 1261 *ret_sel = sel; 1262 1263 /* per spec 2.3.4 */ 1264 lo1n = lo1 / 8; 1265 lo1a = lo1 - (lo1n * 8); 1266 lo2 = desired_lo2 / fref; 1267 lo2n = lo2 / 8; 1268 lo2a = lo2 - (lo2n * 8); 1269 /* scale to fit in 32bit arith */ 1270 lo2num = ((desired_lo2 / 1000) % (fref / 1000)) * 3780 / (fref / 1000); 1271 lo2freq = (lo2a + 8 * lo2n) * fref + lo2num * (fref / 1000) / 3780 * 1000; 1272 1273 if (lo1a < 0 || lo1a > 7 || lo1n < 17 || lo1n > 48 || lo2a < 0 || 1274 lo2a > 7 || lo2n < 17 || lo2n > 30) { 1275 printf("MT2032: parameter out of range\n"); 1276 return -1; 1277 } 1278 /* set up MT2032 register map for transfer over i2c */ 1279 buf[0] = lo1n - 1; 1280 buf[1] = lo1a | (sel << 4); 1281 buf[2] = 0x86; /* LOGC */ 1282 buf[3] = 0x0f; /* reserved */ 1283 buf[4] = 0x1f; 1284 buf[5] = (lo2n - 1) | (lo2a << 5); 1285 if (rfin < 400 * 1000 * 1000) { 1286 buf[6] = 0xe4; 1287 } else { 1288 buf[6] = 0xf4; /* set PKEN per rev 1.2 */ 1289 } 1290 1291 buf[7] = 8 + xogc; 1292 buf[8] = 0xc3; /* reserved */ 1293 buf[9] = 0x4e; /* reserved */ 1294 buf[10] = 0xec; /* reserved */ 1295 buf[11] = (lo2num & 0xff); 1296 buf[12] = (lo2num >> 8) | 0x80; /* Lo2RST */ 1297 1298 return 0; 1299} 1300 1301static int 1302MT2032_CheckLOLock(bktr_ptr_t bktr) 1303{ 1304 int t, lock = 0; 1305 for (t = 0; t < 10; t++) { 1306 lock = MT2032_GetRegister(0x0e) & 0x06; 1307 if (lock == 6) { 1308 break; 1309 } 1310 DELAY(1000); 1311 } 1312 return lock; 1313} 1314 1315static int 1316MT2032_OptimizeVCO(bktr_ptr_t bktr, int sel, int lock) 1317{ 1318 int tad1, lo1a; 1319 1320 tad1 = MT2032_GetRegister(0x0f) & 0x07; 1321 1322 if (tad1 == 0) { 1323 return lock; 1324 } 1325 if (tad1 == 1) { 1326 return lock; 1327 } 1328 if (tad1 == 2) { 1329 if (sel == 0) { 1330 return lock; 1331 } else { 1332 sel--; 1333 } 1334 } else { 1335 if (sel < 4) { 1336 sel++; 1337 } else { 1338 return lock; 1339 } 1340 } 1341 lo1a = MT2032_GetRegister(0x01) & 0x07; 1342 MT2032_SetRegister(0x01, lo1a | (sel << 4)); 1343 lock = MT2032_CheckLOLock(bktr); 1344 return lock; 1345} 1346 1347static int 1348MT2032_SetIFFreq(bktr_ptr_t bktr, int rfin, int if1, int if2, int from, int to) 1349{ 1350 u_char buf[21]; 1351 int lint_try, sel, lock = 0; 1352 1353 if (MT2032_ComputeFreq(rfin, if1, if2, from, to, &buf[0], &sel, MT2032_XOGC) == -1) 1354 return -1; 1355 1356 TDA9887_init(bktr, 0); 1357 1358 printf("%s: MT2032-SetIFFreq: 0x%02X%02X%02X%02X...\n", 1359 bktr_name(bktr), 1360 buf[0x00], buf[0x01], buf[0x02], buf[0x03]); 1361 1362 /* send only the relevant registers per Rev. 1.2 */ 1363 MT2032_SetRegister(0, buf[0x00]); 1364 MT2032_SetRegister(1, buf[0x01]); 1365 MT2032_SetRegister(2, buf[0x02]); 1366 1367 MT2032_SetRegister(5, buf[0x05]); 1368 MT2032_SetRegister(6, buf[0x06]); 1369 MT2032_SetRegister(7, buf[0x07]); 1370 1371 MT2032_SetRegister(11, buf[0x0B]); 1372 MT2032_SetRegister(12, buf[0x0C]); 1373 1374 /* wait for PLLs to lock (per manual), retry LINT if not. */ 1375 for (lint_try = 0; lint_try < 2; lint_try++) { 1376 lock = MT2032_CheckLOLock(bktr); 1377 1378 if (MT2032_OPTIMIZE_VCO) { 1379 lock = MT2032_OptimizeVCO(bktr, sel, lock); 1380 } 1381 if (lock == 6) { 1382 break; 1383 } 1384 /* set LINT to re-init PLLs */ 1385 MT2032_SetRegister(7, 0x80 + 8 + MT2032_XOGC); 1386 DELAY(10000); 1387 MT2032_SetRegister(7, 8 + MT2032_XOGC); 1388 } 1389 if (lock != 6) 1390 printf("%s: PLL didn't lock\n", bktr_name(bktr)); 1391 1392 MT2032_SetRegister(2, 0x20); 1393 1394 TDA9887_init(bktr, 1); 1395 return 0; 1396} 1397 1398static void 1399mt2032_set_tv_freq(bktr_ptr_t bktr, unsigned int freq) 1400{ 1401 int if2,from,to; 1402 1403 from=32900*1000; 1404 to=39900*1000; 1405 if2=38900*1000; 1406 1407 printf("%s: setting frequency to %d\n", bktr_name(bktr), freq*62500); 1408 MT2032_SetIFFreq(bktr, freq*62500 /* freq*1000*1000/16 */, 1409 1090*1000*1000, if2, from, to); 1410} |
|