Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6:
V4L/DVB (9624): CVE-2008-5033: fix OOPS on tvaudio when controlling bass/treble
V4L/DVB (9623): tvaudio: Improve debug msg by printing something more human
V4L/DVB (9622): tvaudio: Improve comments and remove a unneeded prototype
V4L/DVB (9621): Avoid writing outside shadow.bytes[] array
V4L/DVB (9620): tvaudio: use a direct reference for chip description
V4L/DVB (9619): tvaudio: update initial comments
V4L/DVB (9618): tvaudio: add additional logic to avoid OOPS
V4L/DVB (9617): tvtime: remove generic_checkmode callback
V4L/DVB (9616): tvaudio: cleanup - group all callbacks together
V4L/DVB (9615): tvaudio: instead of using a magic number, use ARRAY_SIZE
V4L/DVB (9613): tvaudio: fix a memory leak

+149 -82
+149 -82
drivers/media/video/tvaudio.c
··· 1 1 /* 2 - * experimental driver for simple i2c audio chips. 2 + * Driver for simple i2c audio chips. 3 3 * 4 4 * Copyright (c) 2000 Gerd Knorr 5 5 * based on code by: 6 6 * Eric Sandeen (eric_sandeen@bigfoot.com) 7 7 * Steve VanDeBogart (vandebo@uclink.berkeley.edu) 8 8 * Greg Alexander (galexand@acm.org) 9 + * 10 + * Copyright(c) 2005-2008 Mauro Carvalho Chehab 11 + * - Some cleanups, code fixes, etc 12 + * - Convert it to V4L2 API 9 13 * 10 14 * This code is placed under the terms of the GNU General Public License 11 15 * ··· 34 30 35 31 #include <media/tvaudio.h> 36 32 #include <media/v4l2-common.h> 33 + #include <media/v4l2-ioctl.h> 37 34 #include <media/v4l2-chip-ident.h> 38 35 #include <media/v4l2-i2c-drv-legacy.h> 39 36 ··· 63 58 typedef int (*initialize)(struct CHIPSTATE*); 64 59 typedef int (*getmode)(struct CHIPSTATE*); 65 60 typedef void (*setmode)(struct CHIPSTATE*, int mode); 66 - typedef void (*checkmode)(struct CHIPSTATE*); 67 61 68 62 /* i2c command */ 69 63 typedef struct AUDIOCMD { ··· 83 79 #define CHIP_HAS_VOLUME 1 84 80 #define CHIP_HAS_BASSTREBLE 2 85 81 #define CHIP_HAS_INPUTSEL 4 82 + #define CHIP_NEED_CHECKMODE 8 86 83 87 84 /* various i2c command sequences */ 88 85 audiocmd init; ··· 101 96 getmode getmode; 102 97 setmode setmode; 103 98 104 - /* check / autoswitch audio after channel switches */ 105 - checkmode checkmode; 106 - 107 99 /* input switch register + values for v4l inputs */ 108 100 int inputreg; 109 101 int inputmap[4]; 110 102 int inputmute; 111 103 int inputmask; 112 104 }; 113 - static struct CHIPDESC chiplist[]; 114 105 115 106 /* current state of the chip */ 116 107 struct CHIPSTATE { 117 108 struct i2c_client *c; 118 109 119 - /* index into CHIPDESC array */ 120 - int type; 110 + /* chip-specific description - should point to 111 + an entry at CHIPDESC table */ 112 + struct CHIPDESC *desc; 121 113 122 114 /* shadow register set */ 123 115 audiocmd shadow; ··· 154 152 { 155 153 unsigned char buffer[2]; 156 154 157 - if (-1 == subaddr) { 155 + if (subaddr < 0) { 158 156 v4l_dbg(1, debug, chip->c, "%s: chip_write: 0x%x\n", 159 157 chip->c->name, val); 160 158 chip->shadow.bytes[1] = val; ··· 165 163 return -1; 166 164 } 167 165 } else { 166 + if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) { 167 + v4l_info(chip->c, 168 + "Tried to access a non-existent register: %d\n", 169 + subaddr); 170 + return -EINVAL; 171 + } 172 + 168 173 v4l_dbg(1, debug, chip->c, "%s: chip_write: reg%d=0x%x\n", 169 174 chip->c->name, subaddr, val); 170 175 chip->shadow.bytes[subaddr+1] = val; ··· 186 177 return 0; 187 178 } 188 179 189 - static int chip_write_masked(struct CHIPSTATE *chip, int subaddr, int val, int mask) 180 + static int chip_write_masked(struct CHIPSTATE *chip, 181 + int subaddr, int val, int mask) 190 182 { 191 183 if (mask != 0) { 192 - if (-1 == subaddr) { 184 + if (subaddr < 0) { 193 185 val = (chip->shadow.bytes[1] & ~mask) | (val & mask); 194 186 } else { 187 + if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) { 188 + v4l_info(chip->c, 189 + "Tried to access a non-existent register: %d\n", 190 + subaddr); 191 + return -EINVAL; 192 + } 193 + 195 194 val = (chip->shadow.bytes[subaddr+1] & ~mask) | (val & mask); 196 195 } 197 196 } ··· 245 228 if (0 == cmd->count) 246 229 return 0; 247 230 231 + if (cmd->count + cmd->bytes[0] - 1 >= ARRAY_SIZE(chip->shadow.bytes)) { 232 + v4l_info(chip->c, 233 + "Tried to access a non-existent register range: %d to %d\n", 234 + cmd->bytes[0] + 1, cmd->bytes[0] + cmd->count - 1); 235 + return -EINVAL; 236 + } 237 + 238 + /* FIXME: it seems that the shadow bytes are wrong bellow !*/ 239 + 248 240 /* update our shadow register set; print bytes if (debug > 0) */ 249 241 v4l_dbg(1, debug, chip->c, "%s: chip_cmd(%s): reg=%d, data:", 250 242 chip->c->name, name,cmd->bytes[0]); ··· 289 263 static int chip_thread(void *data) 290 264 { 291 265 struct CHIPSTATE *chip = data; 292 - struct CHIPDESC *desc = chiplist + chip->type; 266 + struct CHIPDESC *desc = chip->desc; 267 + int mode; 293 268 294 269 v4l_dbg(1, debug, chip->c, "%s: thread started\n", chip->c->name); 295 270 set_freezable(); ··· 309 282 continue; 310 283 311 284 /* have a look what's going on */ 312 - desc->checkmode(chip); 285 + mode = desc->getmode(chip); 286 + if (mode == chip->prevmode) 287 + continue; 288 + 289 + /* chip detected a new audio mode - set it */ 290 + v4l_dbg(1, debug, chip->c, "%s: thread checkmode\n", 291 + chip->c->name); 292 + 293 + chip->prevmode = mode; 294 + 295 + if (mode & V4L2_TUNER_MODE_STEREO) 296 + desc->setmode(chip, V4L2_TUNER_MODE_STEREO); 297 + if (mode & V4L2_TUNER_MODE_LANG1_LANG2) 298 + desc->setmode(chip, V4L2_TUNER_MODE_STEREO); 299 + else if (mode & V4L2_TUNER_MODE_LANG1) 300 + desc->setmode(chip, V4L2_TUNER_MODE_LANG1); 301 + else if (mode & V4L2_TUNER_MODE_LANG2) 302 + desc->setmode(chip, V4L2_TUNER_MODE_LANG2); 303 + else 304 + desc->setmode(chip, V4L2_TUNER_MODE_MONO); 313 305 314 306 /* schedule next check */ 315 307 mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000)); ··· 336 290 337 291 v4l_dbg(1, debug, chip->c, "%s: thread exiting\n", chip->c->name); 338 292 return 0; 339 - } 340 - 341 - static void generic_checkmode(struct CHIPSTATE *chip) 342 - { 343 - struct CHIPDESC *desc = chiplist + chip->type; 344 - int mode = desc->getmode(chip); 345 - 346 - if (mode == chip->prevmode) 347 - return; 348 - 349 - v4l_dbg(1, debug, chip->c, "%s: thread checkmode\n", chip->c->name); 350 - chip->prevmode = mode; 351 - 352 - if (mode & V4L2_TUNER_MODE_STEREO) 353 - desc->setmode(chip,V4L2_TUNER_MODE_STEREO); 354 - if (mode & V4L2_TUNER_MODE_LANG1_LANG2) 355 - desc->setmode(chip,V4L2_TUNER_MODE_STEREO); 356 - else if (mode & V4L2_TUNER_MODE_LANG1) 357 - desc->setmode(chip,V4L2_TUNER_MODE_LANG1); 358 - else if (mode & V4L2_TUNER_MODE_LANG2) 359 - desc->setmode(chip,V4L2_TUNER_MODE_LANG2); 360 - else 361 - desc->setmode(chip,V4L2_TUNER_MODE_MONO); 362 293 } 363 294 364 295 /* ---------------------------------------------------------------------- */ ··· 800 777 char *name; 801 778 audiocmd cmd; 802 779 } tda9874a_modelist[9] = { 803 - { "A2, B/G", 780 + { "A2, B/G", /* default */ 804 781 { 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x77,0xA0,0x00, 0x00,0x00 }} }, 805 782 { "A2, M (Korea)", 806 783 { 9, { TDA9874A_C1FRA, 0x5D,0xC0,0x00, 0x62,0x6A,0xAA, 0x20,0x22 }} }, ··· 814 791 { 9, { TDA9874A_C1FRA, 0x7D,0x00,0x00, 0x88,0x8A,0xAA, 0x08,0x33 }} }, 815 792 { "NICAM, B/G", 816 793 { 9, { TDA9874A_C1FRA, 0x72,0x95,0x55, 0x79,0xEA,0xAA, 0x08,0x33 }} }, 817 - { "NICAM, D/K", /* default */ 794 + { "NICAM, D/K", 818 795 { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x08,0x33 }} }, 819 796 { "NICAM, L", 820 797 { 9, { TDA9874A_C1FRA, 0x87,0x6A,0xAA, 0x79,0xEA,0xAA, 0x09,0x33 }} } ··· 1004 981 { 1005 982 if (tda9874a_SIF > 2) 1006 983 tda9874a_SIF = 1; 1007 - if (tda9874a_STD > 8) 984 + if (tda9874a_STD >= ARRAY_SIZE(tda9874a_modelist)) 1008 985 tda9874a_STD = 0; 1009 986 if(tda9874a_AMSEL > 1) 1010 987 tda9874a_AMSEL = 0; ··· 1112 1089 1113 1090 static int tda8425_initialize(struct CHIPSTATE *chip) 1114 1091 { 1115 - struct CHIPDESC *desc = chiplist + chip->type; 1092 + struct CHIPDESC *desc = chip->desc; 1116 1093 int inputmap[4] = { /* tuner */ TDA8425_S1_CH2, /* radio */ TDA8425_S1_CH1, 1117 1094 /* extern */ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF}; 1118 1095 ··· 1282 1259 .addr_lo = I2C_ADDR_TDA9840 >> 1, 1283 1260 .addr_hi = I2C_ADDR_TDA9840 >> 1, 1284 1261 .registers = 5, 1262 + .flags = CHIP_NEED_CHECKMODE, 1285 1263 1264 + /* callbacks */ 1286 1265 .checkit = tda9840_checkit, 1287 1266 .getmode = tda9840_getmode, 1288 1267 .setmode = tda9840_setmode, 1289 - .checkmode = generic_checkmode, 1290 1268 1291 1269 .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN 1292 1270 /* ,TDA9840_SW, TDA9840_MONO */} } 1293 1271 }, 1294 1272 { 1295 1273 .name = "tda9873h", 1296 - .checkit = tda9873_checkit, 1297 1274 .insmodopt = &tda9873, 1298 1275 .addr_lo = I2C_ADDR_TDA985x_L >> 1, 1299 1276 .addr_hi = I2C_ADDR_TDA985x_H >> 1, 1300 1277 .registers = 3, 1301 - .flags = CHIP_HAS_INPUTSEL, 1278 + .flags = CHIP_HAS_INPUTSEL | CHIP_NEED_CHECKMODE, 1302 1279 1280 + /* callbacks */ 1281 + .checkit = tda9873_checkit, 1303 1282 .getmode = tda9873_getmode, 1304 1283 .setmode = tda9873_setmode, 1305 - .checkmode = generic_checkmode, 1306 1284 1307 1285 .init = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } }, 1308 1286 .inputreg = TDA9873_SW, ··· 1314 1290 }, 1315 1291 { 1316 1292 .name = "tda9874h/a", 1317 - .checkit = tda9874a_checkit, 1318 - .initialize = tda9874a_initialize, 1319 1293 .insmodopt = &tda9874a, 1320 1294 .addr_lo = I2C_ADDR_TDA9874 >> 1, 1321 1295 .addr_hi = I2C_ADDR_TDA9874 >> 1, 1296 + .flags = CHIP_NEED_CHECKMODE, 1322 1297 1298 + /* callbacks */ 1299 + .initialize = tda9874a_initialize, 1300 + .checkit = tda9874a_checkit, 1323 1301 .getmode = tda9874a_getmode, 1324 1302 .setmode = tda9874a_setmode, 1325 - .checkmode = generic_checkmode, 1326 1303 }, 1327 1304 { 1328 1305 .name = "tda9850", ··· 1349 1324 .rightreg = TDA9855_VR, 1350 1325 .bassreg = TDA9855_BA, 1351 1326 .treblereg = TDA9855_TR, 1327 + 1328 + /* callbacks */ 1352 1329 .volfunc = tda9855_volume, 1353 1330 .bassfunc = tda9855_bass, 1354 1331 .treblefunc = tda9855_treble, 1355 - 1356 1332 .getmode = tda985x_getmode, 1357 1333 .setmode = tda985x_setmode, 1358 1334 ··· 1374 1348 .rightreg = TEA6300_VL, 1375 1349 .bassreg = TEA6300_BA, 1376 1350 .treblereg = TEA6300_TR, 1351 + 1352 + /* callbacks */ 1377 1353 .volfunc = tea6300_shift10, 1378 1354 .bassfunc = tea6300_shift12, 1379 1355 .treblefunc = tea6300_shift12, ··· 1386 1358 }, 1387 1359 { 1388 1360 .name = "tea6320", 1389 - .initialize = tea6320_initialize, 1390 1361 .insmodopt = &tea6320, 1391 1362 .addr_lo = I2C_ADDR_TEA6300 >> 1, 1392 1363 .addr_hi = I2C_ADDR_TEA6300 >> 1, ··· 1396 1369 .rightreg = TEA6320_V, 1397 1370 .bassreg = TEA6320_BA, 1398 1371 .treblereg = TEA6320_TR, 1372 + 1373 + /* callbacks */ 1374 + .initialize = tea6320_initialize, 1399 1375 .volfunc = tea6320_volume, 1400 1376 .bassfunc = tea6320_shift11, 1401 1377 .treblefunc = tea6320_shift11, ··· 1431 1401 .rightreg = TDA8425_VR, 1432 1402 .bassreg = TDA8425_BA, 1433 1403 .treblereg = TDA8425_TR, 1404 + 1405 + /* callbacks */ 1406 + .initialize = tda8425_initialize, 1434 1407 .volfunc = tda8425_shift10, 1435 1408 .bassfunc = tda8425_shift12, 1436 1409 .treblefunc = tda8425_shift12, 1410 + .setmode = tda8425_setmode, 1437 1411 1438 1412 .inputreg = TDA8425_S1, 1439 1413 .inputmap = { TDA8425_S1_CH1, TDA8425_S1_CH1, TDA8425_S1_CH1 }, 1440 1414 .inputmute = TDA8425_S1_OFF, 1441 1415 1442 - .setmode = tda8425_setmode, 1443 - .initialize = tda8425_initialize, 1444 1416 }, 1445 1417 { 1446 1418 .name = "pic16c54 (PV951)", ··· 1466 1434 .addr_lo = I2C_ADDR_TDA9840 >> 1, 1467 1435 .addr_hi = I2C_ADDR_TDA9840 >> 1, 1468 1436 .registers = 2, 1437 + .flags = CHIP_NEED_CHECKMODE, 1469 1438 1439 + /* callbacks */ 1470 1440 .getmode = ta8874z_getmode, 1471 1441 .setmode = ta8874z_setmode, 1472 - .checkmode = generic_checkmode, 1473 1442 1474 1443 .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}}, 1475 1444 }, ··· 1514 1481 } 1515 1482 if (desc->name == NULL) { 1516 1483 v4l_dbg(1, debug, client, "no matching chip description found\n"); 1484 + kfree(chip); 1517 1485 return -EIO; 1518 1486 } 1519 1487 v4l_info(client, "%s found @ 0x%x (%s)\n", desc->name, client->addr<<1, client->adapter->name); ··· 1528 1494 /* fill required data structures */ 1529 1495 if (!id) 1530 1496 strlcpy(client->name, desc->name, I2C_NAME_SIZE); 1531 - chip->type = desc-chiplist; 1497 + chip->desc = desc; 1532 1498 chip->shadow.count = desc->registers+1; 1533 1499 chip->prevmode = -1; 1534 1500 chip->audmode = V4L2_TUNER_MODE_LANG1; ··· 1540 1506 chip_cmd(chip,"init",&desc->init); 1541 1507 1542 1508 if (desc->flags & CHIP_HAS_VOLUME) { 1543 - chip->left = desc->leftinit ? desc->leftinit : 65535; 1544 - chip->right = desc->rightinit ? desc->rightinit : 65535; 1545 - chip_write(chip,desc->leftreg,desc->volfunc(chip->left)); 1546 - chip_write(chip,desc->rightreg,desc->volfunc(chip->right)); 1509 + if (!desc->volfunc) { 1510 + /* This shouldn't be happen. Warn user, but keep working 1511 + without volume controls 1512 + */ 1513 + v4l_info(chip->c, "volume callback undefined!\n"); 1514 + desc->flags &= ~CHIP_HAS_VOLUME; 1515 + } else { 1516 + chip->left = desc->leftinit ? desc->leftinit : 65535; 1517 + chip->right = desc->rightinit ? desc->rightinit : 65535; 1518 + chip_write(chip, desc->leftreg, 1519 + desc->volfunc(chip->left)); 1520 + chip_write(chip, desc->rightreg, 1521 + desc->volfunc(chip->right)); 1522 + } 1547 1523 } 1548 1524 if (desc->flags & CHIP_HAS_BASSTREBLE) { 1549 - chip->treble = desc->trebleinit ? desc->trebleinit : 32768; 1550 - chip->bass = desc->bassinit ? desc->bassinit : 32768; 1551 - chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass)); 1552 - chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble)); 1525 + if (!desc->bassfunc || !desc->treblefunc) { 1526 + /* This shouldn't be happen. Warn user, but keep working 1527 + without bass/treble controls 1528 + */ 1529 + v4l_info(chip->c, "bass/treble callbacks undefined!\n"); 1530 + desc->flags &= ~CHIP_HAS_BASSTREBLE; 1531 + } else { 1532 + chip->treble = desc->trebleinit ? 1533 + desc->trebleinit : 32768; 1534 + chip->bass = desc->bassinit ? 1535 + desc->bassinit : 32768; 1536 + chip_write(chip, desc->bassreg, 1537 + desc->bassfunc(chip->bass)); 1538 + chip_write(chip, desc->treblereg, 1539 + desc->treblefunc(chip->treble)); 1540 + } 1553 1541 } 1554 1542 1555 1543 chip->thread = NULL; 1556 - if (desc->checkmode) { 1544 + if (desc->flags & CHIP_NEED_CHECKMODE) { 1545 + if (!desc->getmode || !desc->setmode) { 1546 + /* This shouldn't be happen. Warn user, but keep working 1547 + without kthread 1548 + */ 1549 + v4l_info(chip->c, "set/get mode callbacks undefined!\n"); 1550 + return 0; 1551 + } 1557 1552 /* start async thread */ 1558 1553 init_timer(&chip->wt); 1559 1554 chip->wt.function = chip_thread_wake; ··· 1615 1552 static int tvaudio_get_ctrl(struct CHIPSTATE *chip, 1616 1553 struct v4l2_control *ctrl) 1617 1554 { 1618 - struct CHIPDESC *desc = chiplist + chip->type; 1555 + struct CHIPDESC *desc = chip->desc; 1619 1556 1620 1557 switch (ctrl->id) { 1621 1558 case V4L2_CID_AUDIO_MUTE: ··· 1639 1576 return 0; 1640 1577 } 1641 1578 case V4L2_CID_AUDIO_BASS: 1642 - if (desc->flags & CHIP_HAS_BASSTREBLE) 1579 + if (!(desc->flags & CHIP_HAS_BASSTREBLE)) 1643 1580 break; 1644 1581 ctrl->value = chip->bass; 1645 1582 return 0; 1646 1583 case V4L2_CID_AUDIO_TREBLE: 1647 - if (desc->flags & CHIP_HAS_BASSTREBLE) 1648 - return -EINVAL; 1584 + if (!(desc->flags & CHIP_HAS_BASSTREBLE)) 1585 + break; 1649 1586 ctrl->value = chip->treble; 1650 1587 return 0; 1651 1588 } ··· 1655 1592 static int tvaudio_set_ctrl(struct CHIPSTATE *chip, 1656 1593 struct v4l2_control *ctrl) 1657 1594 { 1658 - struct CHIPDESC *desc = chiplist + chip->type; 1595 + struct CHIPDESC *desc = chip->desc; 1659 1596 1660 1597 switch (ctrl->id) { 1661 1598 case V4L2_CID_AUDIO_MUTE: ··· 1705 1642 return 0; 1706 1643 } 1707 1644 case V4L2_CID_AUDIO_BASS: 1708 - if (desc->flags & CHIP_HAS_BASSTREBLE) 1645 + if (!(desc->flags & CHIP_HAS_BASSTREBLE)) 1709 1646 break; 1710 1647 chip->bass = ctrl->value; 1711 1648 chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass)); 1712 1649 1713 1650 return 0; 1714 1651 case V4L2_CID_AUDIO_TREBLE: 1715 - if (desc->flags & CHIP_HAS_BASSTREBLE) 1716 - return -EINVAL; 1717 - 1652 + if (!(desc->flags & CHIP_HAS_BASSTREBLE)) 1653 + break; 1718 1654 chip->treble = ctrl->value; 1719 1655 chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble)); 1720 1656 ··· 1730 1668 unsigned int cmd, void *arg) 1731 1669 { 1732 1670 struct CHIPSTATE *chip = i2c_get_clientdata(client); 1733 - struct CHIPDESC *desc = chiplist + chip->type; 1671 + struct CHIPDESC *desc = chip->desc; 1734 1672 1735 - v4l_dbg(1, debug, chip->c, "%s: chip_command 0x%x\n", chip->c->name, cmd); 1673 + if (debug > 0) { 1674 + v4l_i2c_print_ioctl(chip->c, cmd); 1675 + printk("\n"); 1676 + } 1736 1677 1737 1678 switch (cmd) { 1738 1679 case AUDC_SET_RADIO: ··· 1760 1695 break; 1761 1696 case V4L2_CID_AUDIO_BASS: 1762 1697 case V4L2_CID_AUDIO_TREBLE: 1763 - if (desc->flags & CHIP_HAS_BASSTREBLE) 1698 + if (!(desc->flags & CHIP_HAS_BASSTREBLE)) 1764 1699 return -EINVAL; 1765 1700 break; 1766 1701 default: ··· 1857 1792 break; 1858 1793 case VIDIOC_S_FREQUENCY: 1859 1794 chip->mode = 0; /* automatic */ 1860 - if (desc->checkmode && desc->setmode) { 1795 + 1796 + /* For chips that provide getmode and setmode, and doesn't 1797 + automatically follows the stereo carrier, a kthread is 1798 + created to set the audio standard. In this case, when then 1799 + the video channel is changed, tvaudio starts on MONO mode. 1800 + After waiting for 2 seconds, the kernel thread is called, 1801 + to follow whatever audio standard is pointed by the 1802 + audio carrier. 1803 + */ 1804 + if (chip->thread) { 1861 1805 desc->setmode(chip,V4L2_TUNER_MODE_MONO); 1862 1806 if (chip->prevmode != V4L2_TUNER_MODE_MONO) 1863 1807 chip->prevmode = -1; /* reset previous mode */ 1864 1808 mod_timer(&chip->wt, jiffies+msecs_to_jiffies(2000)); 1865 - /* the thread will call checkmode() later */ 1866 1809 } 1867 1810 break; 1868 1811 ··· 1909 1836 .legacy_probe = chip_legacy_probe, 1910 1837 .id_table = chip_id, 1911 1838 }; 1912 - 1913 - /* 1914 - * Local variables: 1915 - * c-basic-offset: 8 1916 - * End: 1917 - */