Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: em28xx: split up em28xx_dvb_init to reduce stack size

With CONFIG_KASAN, the init function uses a large amount of kernel stack:

drivers/media/usb/em28xx/em28xx-dvb.c: In function 'em28xx_dvb_init.part.4':
drivers/media/usb/em28xx/em28xx-dvb.c:2061:1: error: the frame size of 3232 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]

Using gcc-7 with -fsanitize-address-use-after-scope makes this even worse:

drivers/media/usb/em28xx/em28xx-dvb.c: In function 'em28xx_dvb_init':
drivers/media/usb/em28xx/em28xx-dvb.c:2069:1: error: the frame size of 4280 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]

By splitting out each part of the switch/case statement that has its own local
variables into a separate function, no single one of them uses more than 500 bytes,
and with a noinline_for_stack annotation we can ensure that they are not merged
back together.

[mchehab@s-opensource.com: fix conflict with changeset
be7fd3c3a8c5 ("media: em28xx: Hauppauge DualHD second tuner functionality")]

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Mauro Carvalho Chehab <>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

authored by

Arnd Bergmann and committed by
Mauro Carvalho Chehab
f410b409 cf68c22f

+520 -451
+520 -451
drivers/media/usb/em28xx/em28xx-dvb.c
··· 932 932 933 933 /* ------------------------------------------------------------------ */ 934 934 935 - static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) 935 + static noinline_for_stack int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) 936 936 { 937 937 struct dvb_frontend *fe; 938 938 struct xc2028_config cfg; ··· 1124 1124 dvb_unregister_adapter(&dvb->adapter); 1125 1125 } 1126 1126 1127 + static noinline_for_stack int em28174_dvb_init_pctv_460e(struct em28xx *dev) 1128 + { 1129 + struct em28xx_dvb *dvb = dev->dvb; 1130 + struct i2c_client *client; 1131 + struct i2c_board_info board_info; 1132 + struct tda10071_platform_data tda10071_pdata = {}; 1133 + struct a8293_platform_data a8293_pdata = {}; 1134 + int result; 1135 + 1136 + /* attach demod + tuner combo */ 1137 + tda10071_pdata.clk = 40444000, /* 40.444 MHz */ 1138 + tda10071_pdata.i2c_wr_max = 64, 1139 + tda10071_pdata.ts_mode = TDA10071_TS_SERIAL, 1140 + tda10071_pdata.pll_multiplier = 20, 1141 + tda10071_pdata.tuner_i2c_addr = 0x14, 1142 + memset(&board_info, 0, sizeof(board_info)); 1143 + strlcpy(board_info.type, "tda10071_cx24118", I2C_NAME_SIZE); 1144 + board_info.addr = 0x55; 1145 + board_info.platform_data = &tda10071_pdata; 1146 + request_module("tda10071"); 1147 + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); 1148 + if (client == NULL || client->dev.driver == NULL) { 1149 + result = -ENODEV; 1150 + goto out_free; 1151 + } 1152 + if (!try_module_get(client->dev.driver->owner)) { 1153 + i2c_unregister_device(client); 1154 + result = -ENODEV; 1155 + goto out_free; 1156 + } 1157 + dvb->fe[0] = tda10071_pdata.get_dvb_frontend(client); 1158 + dvb->i2c_client_demod = client; 1159 + 1160 + /* attach SEC */ 1161 + a8293_pdata.dvb_frontend = dvb->fe[0]; 1162 + memset(&board_info, 0, sizeof(board_info)); 1163 + strlcpy(board_info.type, "a8293", I2C_NAME_SIZE); 1164 + board_info.addr = 0x08; 1165 + board_info.platform_data = &a8293_pdata; 1166 + request_module("a8293"); 1167 + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); 1168 + if (client == NULL || client->dev.driver == NULL) { 1169 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1170 + i2c_unregister_device(dvb->i2c_client_demod); 1171 + result = -ENODEV; 1172 + goto out_free; 1173 + } 1174 + if (!try_module_get(client->dev.driver->owner)) { 1175 + i2c_unregister_device(client); 1176 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1177 + i2c_unregister_device(dvb->i2c_client_demod); 1178 + result = -ENODEV; 1179 + goto out_free; 1180 + } 1181 + dvb->i2c_client_sec = client; 1182 + result = 0; 1183 + out_free: 1184 + return result; 1185 + } 1186 + 1187 + static noinline_for_stack int em28178_dvb_init_pctv_461e(struct em28xx *dev) 1188 + { 1189 + struct em28xx_dvb *dvb = dev->dvb; 1190 + struct i2c_client *client; 1191 + struct i2c_adapter *i2c_adapter; 1192 + struct i2c_board_info board_info; 1193 + struct m88ds3103_platform_data m88ds3103_pdata = {}; 1194 + struct ts2020_config ts2020_config = {}; 1195 + struct a8293_platform_data a8293_pdata = {}; 1196 + int result; 1197 + 1198 + /* attach demod */ 1199 + m88ds3103_pdata.clk = 27000000; 1200 + m88ds3103_pdata.i2c_wr_max = 33; 1201 + m88ds3103_pdata.ts_mode = M88DS3103_TS_PARALLEL; 1202 + m88ds3103_pdata.ts_clk = 16000; 1203 + m88ds3103_pdata.ts_clk_pol = 1; 1204 + m88ds3103_pdata.agc = 0x99; 1205 + memset(&board_info, 0, sizeof(board_info)); 1206 + strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE); 1207 + board_info.addr = 0x68; 1208 + board_info.platform_data = &m88ds3103_pdata; 1209 + request_module("m88ds3103"); 1210 + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); 1211 + if (client == NULL || client->dev.driver == NULL) { 1212 + result = -ENODEV; 1213 + goto out_free; 1214 + } 1215 + if (!try_module_get(client->dev.driver->owner)) { 1216 + i2c_unregister_device(client); 1217 + result = -ENODEV; 1218 + goto out_free; 1219 + } 1220 + dvb->fe[0] = m88ds3103_pdata.get_dvb_frontend(client); 1221 + i2c_adapter = m88ds3103_pdata.get_i2c_adapter(client); 1222 + dvb->i2c_client_demod = client; 1223 + 1224 + /* attach tuner */ 1225 + ts2020_config.fe = dvb->fe[0]; 1226 + memset(&board_info, 0, sizeof(board_info)); 1227 + strlcpy(board_info.type, "ts2022", I2C_NAME_SIZE); 1228 + board_info.addr = 0x60; 1229 + board_info.platform_data = &ts2020_config; 1230 + request_module("ts2020"); 1231 + client = i2c_new_device(i2c_adapter, &board_info); 1232 + if (client == NULL || client->dev.driver == NULL) { 1233 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1234 + i2c_unregister_device(dvb->i2c_client_demod); 1235 + result = -ENODEV; 1236 + goto out_free; 1237 + } 1238 + if (!try_module_get(client->dev.driver->owner)) { 1239 + i2c_unregister_device(client); 1240 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1241 + i2c_unregister_device(dvb->i2c_client_demod); 1242 + result = -ENODEV; 1243 + goto out_free; 1244 + } 1245 + dvb->i2c_client_tuner = client; 1246 + /* delegate signal strength measurement to tuner */ 1247 + dvb->fe[0]->ops.read_signal_strength = 1248 + dvb->fe[0]->ops.tuner_ops.get_rf_strength; 1249 + 1250 + /* attach SEC */ 1251 + a8293_pdata.dvb_frontend = dvb->fe[0]; 1252 + memset(&board_info, 0, sizeof(board_info)); 1253 + strlcpy(board_info.type, "a8293", I2C_NAME_SIZE); 1254 + board_info.addr = 0x08; 1255 + board_info.platform_data = &a8293_pdata; 1256 + request_module("a8293"); 1257 + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); 1258 + if (client == NULL || client->dev.driver == NULL) { 1259 + module_put(dvb->i2c_client_tuner->dev.driver->owner); 1260 + i2c_unregister_device(dvb->i2c_client_tuner); 1261 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1262 + i2c_unregister_device(dvb->i2c_client_demod); 1263 + result = -ENODEV; 1264 + goto out_free; 1265 + } 1266 + if (!try_module_get(client->dev.driver->owner)) { 1267 + i2c_unregister_device(client); 1268 + module_put(dvb->i2c_client_tuner->dev.driver->owner); 1269 + i2c_unregister_device(dvb->i2c_client_tuner); 1270 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1271 + i2c_unregister_device(dvb->i2c_client_demod); 1272 + result = -ENODEV; 1273 + goto out_free; 1274 + } 1275 + dvb->i2c_client_sec = client; 1276 + result = 0; 1277 + out_free: 1278 + return result; 1279 + } 1280 + 1281 + static noinline_for_stack int em28178_dvb_init_pctv_292e(struct em28xx *dev) 1282 + { 1283 + struct em28xx_dvb *dvb = dev->dvb; 1284 + struct i2c_adapter *adapter; 1285 + struct i2c_client *client; 1286 + struct i2c_board_info info; 1287 + struct si2168_config si2168_config; 1288 + struct si2157_config si2157_config; 1289 + int result; 1290 + 1291 + /* attach demod */ 1292 + memset(&si2168_config, 0, sizeof(si2168_config)); 1293 + si2168_config.i2c_adapter = &adapter; 1294 + si2168_config.fe = &dvb->fe[0]; 1295 + si2168_config.ts_mode = SI2168_TS_PARALLEL; 1296 + memset(&info, 0, sizeof(struct i2c_board_info)); 1297 + strlcpy(info.type, "si2168", I2C_NAME_SIZE); 1298 + info.addr = 0x64; 1299 + info.platform_data = &si2168_config; 1300 + request_module(info.type); 1301 + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); 1302 + if (client == NULL || client->dev.driver == NULL) { 1303 + result = -ENODEV; 1304 + goto out_free; 1305 + } 1306 + 1307 + if (!try_module_get(client->dev.driver->owner)) { 1308 + i2c_unregister_device(client); 1309 + result = -ENODEV; 1310 + goto out_free; 1311 + } 1312 + 1313 + dvb->i2c_client_demod = client; 1314 + 1315 + /* attach tuner */ 1316 + memset(&si2157_config, 0, sizeof(si2157_config)); 1317 + si2157_config.fe = dvb->fe[0]; 1318 + si2157_config.if_port = 1; 1319 + #ifdef CONFIG_MEDIA_CONTROLLER_DVB 1320 + si2157_config.mdev = dev->media_dev; 1321 + #endif 1322 + memset(&info, 0, sizeof(struct i2c_board_info)); 1323 + strlcpy(info.type, "si2157", I2C_NAME_SIZE); 1324 + info.addr = 0x60; 1325 + info.platform_data = &si2157_config; 1326 + request_module(info.type); 1327 + client = i2c_new_device(adapter, &info); 1328 + if (client == NULL || client->dev.driver == NULL) { 1329 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1330 + i2c_unregister_device(dvb->i2c_client_demod); 1331 + result = -ENODEV; 1332 + goto out_free; 1333 + } 1334 + 1335 + if (!try_module_get(client->dev.driver->owner)) { 1336 + i2c_unregister_device(client); 1337 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1338 + i2c_unregister_device(dvb->i2c_client_demod); 1339 + result = -ENODEV; 1340 + goto out_free; 1341 + } 1342 + 1343 + dvb->i2c_client_tuner = client; 1344 + dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna; 1345 + result = 0; 1346 + out_free: 1347 + return result; 1348 + } 1349 + 1350 + static noinline_for_stack int em28178_dvb_init_terratec_t2_stick_hd(struct em28xx *dev) 1351 + { 1352 + struct em28xx_dvb *dvb = dev->dvb; 1353 + struct i2c_adapter *adapter; 1354 + struct i2c_client *client; 1355 + struct i2c_board_info info; 1356 + struct si2168_config si2168_config; 1357 + struct si2157_config si2157_config; 1358 + int result; 1359 + 1360 + /* attach demod */ 1361 + memset(&si2168_config, 0, sizeof(si2168_config)); 1362 + si2168_config.i2c_adapter = &adapter; 1363 + si2168_config.fe = &dvb->fe[0]; 1364 + si2168_config.ts_mode = SI2168_TS_PARALLEL; 1365 + memset(&info, 0, sizeof(struct i2c_board_info)); 1366 + strlcpy(info.type, "si2168", I2C_NAME_SIZE); 1367 + info.addr = 0x64; 1368 + info.platform_data = &si2168_config; 1369 + request_module(info.type); 1370 + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); 1371 + if (client == NULL || client->dev.driver == NULL) { 1372 + result = -ENODEV; 1373 + goto out_free; 1374 + } 1375 + 1376 + if (!try_module_get(client->dev.driver->owner)) { 1377 + i2c_unregister_device(client); 1378 + result = -ENODEV; 1379 + goto out_free; 1380 + } 1381 + 1382 + dvb->i2c_client_demod = client; 1383 + 1384 + /* attach tuner */ 1385 + memset(&si2157_config, 0, sizeof(si2157_config)); 1386 + si2157_config.fe = dvb->fe[0]; 1387 + si2157_config.if_port = 0; 1388 + #ifdef CONFIG_MEDIA_CONTROLLER_DVB 1389 + si2157_config.mdev = dev->media_dev; 1390 + #endif 1391 + memset(&info, 0, sizeof(struct i2c_board_info)); 1392 + strlcpy(info.type, "si2146", I2C_NAME_SIZE); 1393 + info.addr = 0x60; 1394 + info.platform_data = &si2157_config; 1395 + request_module("si2157"); 1396 + client = i2c_new_device(adapter, &info); 1397 + if (client == NULL || client->dev.driver == NULL) { 1398 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1399 + i2c_unregister_device(dvb->i2c_client_demod); 1400 + result = -ENODEV; 1401 + goto out_free; 1402 + } 1403 + 1404 + if (!try_module_get(client->dev.driver->owner)) { 1405 + i2c_unregister_device(client); 1406 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1407 + i2c_unregister_device(dvb->i2c_client_demod); 1408 + result = -ENODEV; 1409 + goto out_free; 1410 + } 1411 + 1412 + dvb->i2c_client_tuner = client; 1413 + result = 0; 1414 + out_free: 1415 + return result; 1416 + } 1417 + 1418 + static noinline_for_stack int em28178_dvb_init_plex_px_bcud(struct em28xx *dev) 1419 + { 1420 + struct em28xx_dvb *dvb = dev->dvb; 1421 + struct i2c_client *client; 1422 + struct i2c_board_info info; 1423 + struct tc90522_config tc90522_config; 1424 + struct qm1d1c0042_config qm1d1c0042_config; 1425 + int result; 1426 + 1427 + /* attach demod */ 1428 + memset(&tc90522_config, 0, sizeof(tc90522_config)); 1429 + memset(&info, 0, sizeof(struct i2c_board_info)); 1430 + strlcpy(info.type, "tc90522sat", I2C_NAME_SIZE); 1431 + info.addr = 0x15; 1432 + info.platform_data = &tc90522_config; 1433 + request_module("tc90522"); 1434 + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); 1435 + if (client == NULL || client->dev.driver == NULL) { 1436 + result = -ENODEV; 1437 + goto out_free; 1438 + } 1439 + dvb->i2c_client_demod = client; 1440 + if (!try_module_get(client->dev.driver->owner)) { 1441 + i2c_unregister_device(client); 1442 + result = -ENODEV; 1443 + goto out_free; 1444 + } 1445 + 1446 + /* attach tuner */ 1447 + memset(&qm1d1c0042_config, 0, 1448 + sizeof(qm1d1c0042_config)); 1449 + qm1d1c0042_config.fe = tc90522_config.fe; 1450 + qm1d1c0042_config.lpf = 1; 1451 + memset(&info, 0, sizeof(struct i2c_board_info)); 1452 + strlcpy(info.type, "qm1d1c0042", I2C_NAME_SIZE); 1453 + info.addr = 0x61; 1454 + info.platform_data = &qm1d1c0042_config; 1455 + request_module(info.type); 1456 + client = i2c_new_device(tc90522_config.tuner_i2c, 1457 + &info); 1458 + if (client == NULL || client->dev.driver == NULL) { 1459 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1460 + i2c_unregister_device(dvb->i2c_client_demod); 1461 + result = -ENODEV; 1462 + goto out_free; 1463 + } 1464 + dvb->i2c_client_tuner = client; 1465 + if (!try_module_get(client->dev.driver->owner)) { 1466 + i2c_unregister_device(client); 1467 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1468 + i2c_unregister_device(dvb->i2c_client_demod); 1469 + result = -ENODEV; 1470 + goto out_free; 1471 + } 1472 + dvb->fe[0] = tc90522_config.fe; 1473 + px_bcud_init(dev); 1474 + result = 0; 1475 + out_free: 1476 + return result; 1477 + } 1478 + 1479 + static noinline_for_stack int em28174_dvb_init_hauppauge_wintv_dualhd_dvb(struct em28xx *dev) 1480 + { 1481 + struct em28xx_dvb *dvb = dev->dvb; 1482 + struct i2c_adapter *adapter; 1483 + struct i2c_client *client; 1484 + struct i2c_board_info info; 1485 + struct si2168_config si2168_config; 1486 + struct si2157_config si2157_config; 1487 + int result; 1488 + 1489 + /* attach demod */ 1490 + memset(&si2168_config, 0, sizeof(si2168_config)); 1491 + si2168_config.i2c_adapter = &adapter; 1492 + si2168_config.fe = &dvb->fe[0]; 1493 + si2168_config.ts_mode = SI2168_TS_SERIAL; 1494 + memset(&info, 0, sizeof(struct i2c_board_info)); 1495 + strlcpy(info.type, "si2168", I2C_NAME_SIZE); 1496 + if (dev->ts == PRIMARY_TS) 1497 + info.addr = 0x64; 1498 + else 1499 + info.addr = 0x67; 1500 + info.platform_data = &si2168_config; 1501 + request_module(info.type); 1502 + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); 1503 + if (client == NULL || client->dev.driver == NULL) { 1504 + result = -ENODEV; 1505 + goto out_free; 1506 + } 1507 + 1508 + if (!try_module_get(client->dev.driver->owner)) { 1509 + i2c_unregister_device(client); 1510 + result = -ENODEV; 1511 + goto out_free; 1512 + } 1513 + 1514 + dvb->i2c_client_demod = client; 1515 + 1516 + /* attach tuner */ 1517 + memset(&si2157_config, 0, sizeof(si2157_config)); 1518 + si2157_config.fe = dvb->fe[0]; 1519 + si2157_config.if_port = 1; 1520 + #ifdef CONFIG_MEDIA_CONTROLLER_DVB 1521 + si2157_config.mdev = dev->media_dev; 1522 + #endif 1523 + memset(&info, 0, sizeof(struct i2c_board_info)); 1524 + strlcpy(info.type, "si2157", I2C_NAME_SIZE); 1525 + if (dev->ts == PRIMARY_TS) 1526 + info.addr = 0x60; 1527 + else 1528 + info.addr = 0x63; 1529 + info.platform_data = &si2157_config; 1530 + request_module(info.type); 1531 + client = i2c_new_device(adapter, &info); 1532 + if (client == NULL || client->dev.driver == NULL) { 1533 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1534 + i2c_unregister_device(dvb->i2c_client_demod); 1535 + result = -ENODEV; 1536 + goto out_free; 1537 + } 1538 + 1539 + if (!try_module_get(client->dev.driver->owner)) { 1540 + i2c_unregister_device(client); 1541 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1542 + i2c_unregister_device(dvb->i2c_client_demod); 1543 + result = -ENODEV; 1544 + goto out_free; 1545 + } 1546 + 1547 + dvb->i2c_client_tuner = client; 1548 + result = 0; 1549 + out_free: 1550 + return result; 1551 + } 1552 + 1553 + static int em28174_dvb_init_hauppauge_wintv_dualhd_01595(struct em28xx *dev) 1554 + { 1555 + struct em28xx_dvb *dvb = dev->dvb; 1556 + struct i2c_adapter *adapter; 1557 + struct i2c_client *client; 1558 + struct i2c_board_info info = {}; 1559 + struct lgdt3306a_config lgdt3306a_config; 1560 + struct si2157_config si2157_config = {}; 1561 + int result; 1562 + 1563 + /* attach demod */ 1564 + lgdt3306a_config = hauppauge_01595_lgdt3306a_config; 1565 + lgdt3306a_config.fe = &dvb->fe[0]; 1566 + lgdt3306a_config.i2c_adapter = &adapter; 1567 + strlcpy(info.type, "lgdt3306a", sizeof(info.type)); 1568 + if (dev->ts == PRIMARY_TS) 1569 + info.addr = 0x59; 1570 + else 1571 + info.addr = 0x0e; 1572 + info.platform_data = &lgdt3306a_config; 1573 + request_module(info.type); 1574 + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], 1575 + &info); 1576 + if (client == NULL || client->dev.driver == NULL) { 1577 + result = -ENODEV; 1578 + goto out_free; 1579 + } 1580 + 1581 + if (!try_module_get(client->dev.driver->owner)) { 1582 + i2c_unregister_device(client); 1583 + result = -ENODEV; 1584 + goto out_free; 1585 + } 1586 + 1587 + dvb->i2c_client_demod = client; 1588 + 1589 + /* attach tuner */ 1590 + si2157_config.fe = dvb->fe[0]; 1591 + si2157_config.if_port = 1; 1592 + si2157_config.inversion = 1; 1593 + #ifdef CONFIG_MEDIA_CONTROLLER_DVB 1594 + si2157_config.mdev = dev->media_dev; 1595 + #endif 1596 + memset(&info, 0, sizeof(struct i2c_board_info)); 1597 + strlcpy(info.type, "si2157", sizeof(info.type)); 1598 + if (dev->ts == PRIMARY_TS) 1599 + info.addr = 0x60; 1600 + else 1601 + info.addr = 0x62; 1602 + info.platform_data = &si2157_config; 1603 + request_module(info.type); 1604 + 1605 + client = i2c_new_device(adapter, &info); 1606 + if (client == NULL || client->dev.driver == NULL) { 1607 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1608 + i2c_unregister_device(dvb->i2c_client_demod); 1609 + result = -ENODEV; 1610 + goto out_free; 1611 + } 1612 + if (!try_module_get(client->dev.driver->owner)) { 1613 + i2c_unregister_device(client); 1614 + module_put(dvb->i2c_client_demod->dev.driver->owner); 1615 + i2c_unregister_device(dvb->i2c_client_demod); 1616 + result = -ENODEV; 1617 + goto out_free; 1618 + } 1619 + 1620 + dvb->i2c_client_tuner = client; 1621 + result = 0; 1622 + out_free: 1623 + return result; 1624 + } 1127 1625 static int em28xx_dvb_init(struct em28xx *dev) 1128 1626 { 1129 1627 int result = 0, dvb_alt = 0; ··· 1924 1426 &dev->i2c_adap[dev->def_i2c_bus], 1925 1427 &c3tech_duo_tda18271_config); 1926 1428 break; 1927 - case EM28174_BOARD_PCTV_460E: { 1928 - struct i2c_client *client; 1929 - struct i2c_board_info board_info; 1930 - struct tda10071_platform_data tda10071_pdata = {}; 1931 - struct a8293_platform_data a8293_pdata = {}; 1932 - 1933 - /* attach demod + tuner combo */ 1934 - tda10071_pdata.clk = 40444000, /* 40.444 MHz */ 1935 - tda10071_pdata.i2c_wr_max = 64, 1936 - tda10071_pdata.ts_mode = TDA10071_TS_SERIAL, 1937 - tda10071_pdata.pll_multiplier = 20, 1938 - tda10071_pdata.tuner_i2c_addr = 0x14, 1939 - memset(&board_info, 0, sizeof(board_info)); 1940 - strlcpy(board_info.type, "tda10071_cx24118", I2C_NAME_SIZE); 1941 - board_info.addr = 0x55; 1942 - board_info.platform_data = &tda10071_pdata; 1943 - request_module("tda10071"); 1944 - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); 1945 - if (client == NULL || client->dev.driver == NULL) { 1946 - result = -ENODEV; 1429 + case EM28174_BOARD_PCTV_460E: 1430 + result = em28174_dvb_init_pctv_460e(dev); 1431 + if (result) 1947 1432 goto out_free; 1948 - } 1949 - if (!try_module_get(client->dev.driver->owner)) { 1950 - i2c_unregister_device(client); 1951 - result = -ENODEV; 1952 - goto out_free; 1953 - } 1954 - dvb->fe[0] = tda10071_pdata.get_dvb_frontend(client); 1955 - dvb->i2c_client_demod = client; 1956 - 1957 - /* attach SEC */ 1958 - a8293_pdata.dvb_frontend = dvb->fe[0]; 1959 - memset(&board_info, 0, sizeof(board_info)); 1960 - strlcpy(board_info.type, "a8293", I2C_NAME_SIZE); 1961 - board_info.addr = 0x08; 1962 - board_info.platform_data = &a8293_pdata; 1963 - request_module("a8293"); 1964 - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); 1965 - if (client == NULL || client->dev.driver == NULL) { 1966 - module_put(dvb->i2c_client_demod->dev.driver->owner); 1967 - i2c_unregister_device(dvb->i2c_client_demod); 1968 - result = -ENODEV; 1969 - goto out_free; 1970 - } 1971 - if (!try_module_get(client->dev.driver->owner)) { 1972 - i2c_unregister_device(client); 1973 - module_put(dvb->i2c_client_demod->dev.driver->owner); 1974 - i2c_unregister_device(dvb->i2c_client_demod); 1975 - result = -ENODEV; 1976 - goto out_free; 1977 - } 1978 - dvb->i2c_client_sec = client; 1979 1433 break; 1980 - } 1981 1434 case EM2874_BOARD_DELOCK_61959: 1982 1435 case EM2874_BOARD_MAXMEDIA_UB425_TC: 1983 1436 /* attach demodulator */ ··· 2075 1626 } 2076 1627 } 2077 1628 break; 2078 - case EM28178_BOARD_PCTV_461E: { 2079 - struct i2c_client *client; 2080 - struct i2c_adapter *i2c_adapter; 2081 - struct i2c_board_info board_info; 2082 - struct m88ds3103_platform_data m88ds3103_pdata = {}; 2083 - struct ts2020_config ts2020_config = {}; 2084 - struct a8293_platform_data a8293_pdata = {}; 2085 - 2086 - /* attach demod */ 2087 - m88ds3103_pdata.clk = 27000000; 2088 - m88ds3103_pdata.i2c_wr_max = 33; 2089 - m88ds3103_pdata.ts_mode = M88DS3103_TS_PARALLEL; 2090 - m88ds3103_pdata.ts_clk = 16000; 2091 - m88ds3103_pdata.ts_clk_pol = 1; 2092 - m88ds3103_pdata.agc = 0x99; 2093 - memset(&board_info, 0, sizeof(board_info)); 2094 - strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE); 2095 - board_info.addr = 0x68; 2096 - board_info.platform_data = &m88ds3103_pdata; 2097 - request_module("m88ds3103"); 2098 - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); 2099 - if (client == NULL || client->dev.driver == NULL) { 2100 - result = -ENODEV; 1629 + case EM28178_BOARD_PCTV_461E: 1630 + result = em28178_dvb_init_pctv_461e(dev); 1631 + if (result) 2101 1632 goto out_free; 2102 - } 2103 - if (!try_module_get(client->dev.driver->owner)) { 2104 - i2c_unregister_device(client); 2105 - result = -ENODEV; 2106 - goto out_free; 2107 - } 2108 - dvb->fe[0] = m88ds3103_pdata.get_dvb_frontend(client); 2109 - i2c_adapter = m88ds3103_pdata.get_i2c_adapter(client); 2110 - dvb->i2c_client_demod = client; 2111 - 2112 - /* attach tuner */ 2113 - ts2020_config.fe = dvb->fe[0]; 2114 - memset(&board_info, 0, sizeof(board_info)); 2115 - strlcpy(board_info.type, "ts2022", I2C_NAME_SIZE); 2116 - board_info.addr = 0x60; 2117 - board_info.platform_data = &ts2020_config; 2118 - request_module("ts2020"); 2119 - client = i2c_new_device(i2c_adapter, &board_info); 2120 - if (client == NULL || client->dev.driver == NULL) { 2121 - module_put(dvb->i2c_client_demod->dev.driver->owner); 2122 - i2c_unregister_device(dvb->i2c_client_demod); 2123 - result = -ENODEV; 2124 - goto out_free; 2125 - } 2126 - if (!try_module_get(client->dev.driver->owner)) { 2127 - i2c_unregister_device(client); 2128 - module_put(dvb->i2c_client_demod->dev.driver->owner); 2129 - i2c_unregister_device(dvb->i2c_client_demod); 2130 - result = -ENODEV; 2131 - goto out_free; 2132 - } 2133 - dvb->i2c_client_tuner = client; 2134 - /* delegate signal strength measurement to tuner */ 2135 - dvb->fe[0]->ops.read_signal_strength = 2136 - dvb->fe[0]->ops.tuner_ops.get_rf_strength; 2137 - 2138 - /* attach SEC */ 2139 - a8293_pdata.dvb_frontend = dvb->fe[0]; 2140 - memset(&board_info, 0, sizeof(board_info)); 2141 - strlcpy(board_info.type, "a8293", I2C_NAME_SIZE); 2142 - board_info.addr = 0x08; 2143 - board_info.platform_data = &a8293_pdata; 2144 - request_module("a8293"); 2145 - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &board_info); 2146 - if (client == NULL || client->dev.driver == NULL) { 2147 - module_put(dvb->i2c_client_tuner->dev.driver->owner); 2148 - i2c_unregister_device(dvb->i2c_client_tuner); 2149 - module_put(dvb->i2c_client_demod->dev.driver->owner); 2150 - i2c_unregister_device(dvb->i2c_client_demod); 2151 - result = -ENODEV; 2152 - goto out_free; 2153 - } 2154 - if (!try_module_get(client->dev.driver->owner)) { 2155 - i2c_unregister_device(client); 2156 - module_put(dvb->i2c_client_tuner->dev.driver->owner); 2157 - i2c_unregister_device(dvb->i2c_client_tuner); 2158 - module_put(dvb->i2c_client_demod->dev.driver->owner); 2159 - i2c_unregister_device(dvb->i2c_client_demod); 2160 - result = -ENODEV; 2161 - goto out_free; 2162 - } 2163 - dvb->i2c_client_sec = client; 2164 1633 break; 2165 - } 2166 1634 case EM28178_BOARD_PCTV_292E: 2167 - { 2168 - struct i2c_adapter *adapter; 2169 - struct i2c_client *client; 2170 - struct i2c_board_info info; 2171 - struct si2168_config si2168_config; 2172 - struct si2157_config si2157_config; 2173 - 2174 - /* attach demod */ 2175 - memset(&si2168_config, 0, sizeof(si2168_config)); 2176 - si2168_config.i2c_adapter = &adapter; 2177 - si2168_config.fe = &dvb->fe[0]; 2178 - si2168_config.ts_mode = SI2168_TS_PARALLEL; 2179 - memset(&info, 0, sizeof(struct i2c_board_info)); 2180 - strlcpy(info.type, "si2168", I2C_NAME_SIZE); 2181 - info.addr = 0x64; 2182 - info.platform_data = &si2168_config; 2183 - request_module(info.type); 2184 - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); 2185 - if (client == NULL || client->dev.driver == NULL) { 2186 - result = -ENODEV; 2187 - goto out_free; 2188 - } 2189 - 2190 - if (!try_module_get(client->dev.driver->owner)) { 2191 - i2c_unregister_device(client); 2192 - result = -ENODEV; 2193 - goto out_free; 2194 - } 2195 - 2196 - dvb->i2c_client_demod = client; 2197 - 2198 - /* attach tuner */ 2199 - memset(&si2157_config, 0, sizeof(si2157_config)); 2200 - si2157_config.fe = dvb->fe[0]; 2201 - si2157_config.if_port = 1; 2202 - #ifdef CONFIG_MEDIA_CONTROLLER_DVB 2203 - si2157_config.mdev = dev->media_dev; 2204 - #endif 2205 - memset(&info, 0, sizeof(struct i2c_board_info)); 2206 - strlcpy(info.type, "si2157", I2C_NAME_SIZE); 2207 - info.addr = 0x60; 2208 - info.platform_data = &si2157_config; 2209 - request_module(info.type); 2210 - client = i2c_new_device(adapter, &info); 2211 - if (client == NULL || client->dev.driver == NULL) { 2212 - module_put(dvb->i2c_client_demod->dev.driver->owner); 2213 - i2c_unregister_device(dvb->i2c_client_demod); 2214 - result = -ENODEV; 2215 - goto out_free; 2216 - } 2217 - 2218 - if (!try_module_get(client->dev.driver->owner)) { 2219 - i2c_unregister_device(client); 2220 - module_put(dvb->i2c_client_demod->dev.driver->owner); 2221 - i2c_unregister_device(dvb->i2c_client_demod); 2222 - result = -ENODEV; 2223 - goto out_free; 2224 - } 2225 - 2226 - dvb->i2c_client_tuner = client; 2227 - dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna; 2228 - } 1635 + result = em28178_dvb_init_pctv_292e(dev); 1636 + if (result) 1637 + goto out_free; 2229 1638 break; 2230 1639 case EM28178_BOARD_TERRATEC_T2_STICK_HD: 2231 - { 2232 - struct i2c_adapter *adapter; 2233 - struct i2c_client *client; 2234 - struct i2c_board_info info; 2235 - struct si2168_config si2168_config; 2236 - struct si2157_config si2157_config; 2237 - 2238 - /* attach demod */ 2239 - memset(&si2168_config, 0, sizeof(si2168_config)); 2240 - si2168_config.i2c_adapter = &adapter; 2241 - si2168_config.fe = &dvb->fe[0]; 2242 - si2168_config.ts_mode = SI2168_TS_PARALLEL; 2243 - memset(&info, 0, sizeof(struct i2c_board_info)); 2244 - strlcpy(info.type, "si2168", I2C_NAME_SIZE); 2245 - info.addr = 0x64; 2246 - info.platform_data = &si2168_config; 2247 - request_module(info.type); 2248 - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); 2249 - if (client == NULL || client->dev.driver == NULL) { 2250 - result = -ENODEV; 2251 - goto out_free; 2252 - } 2253 - 2254 - if (!try_module_get(client->dev.driver->owner)) { 2255 - i2c_unregister_device(client); 2256 - result = -ENODEV; 2257 - goto out_free; 2258 - } 2259 - 2260 - dvb->i2c_client_demod = client; 2261 - 2262 - /* attach tuner */ 2263 - memset(&si2157_config, 0, sizeof(si2157_config)); 2264 - si2157_config.fe = dvb->fe[0]; 2265 - si2157_config.if_port = 0; 2266 - #ifdef CONFIG_MEDIA_CONTROLLER_DVB 2267 - si2157_config.mdev = dev->media_dev; 2268 - #endif 2269 - memset(&info, 0, sizeof(struct i2c_board_info)); 2270 - strlcpy(info.type, "si2146", I2C_NAME_SIZE); 2271 - info.addr = 0x60; 2272 - info.platform_data = &si2157_config; 2273 - request_module("si2157"); 2274 - client = i2c_new_device(adapter, &info); 2275 - if (client == NULL || client->dev.driver == NULL) { 2276 - module_put(dvb->i2c_client_demod->dev.driver->owner); 2277 - i2c_unregister_device(dvb->i2c_client_demod); 2278 - result = -ENODEV; 2279 - goto out_free; 2280 - } 2281 - 2282 - if (!try_module_get(client->dev.driver->owner)) { 2283 - i2c_unregister_device(client); 2284 - module_put(dvb->i2c_client_demod->dev.driver->owner); 2285 - i2c_unregister_device(dvb->i2c_client_demod); 2286 - result = -ENODEV; 2287 - goto out_free; 2288 - } 2289 - 2290 - dvb->i2c_client_tuner = client; 2291 - } 1640 + result = em28178_dvb_init_terratec_t2_stick_hd(dev); 1641 + if (result) 1642 + goto out_free; 2292 1643 break; 2293 - 2294 1644 case EM28178_BOARD_PLEX_PX_BCUD: 2295 - { 2296 - struct i2c_client *client; 2297 - struct i2c_board_info info; 2298 - struct tc90522_config tc90522_config; 2299 - struct qm1d1c0042_config qm1d1c0042_config; 2300 - 2301 - /* attach demod */ 2302 - memset(&tc90522_config, 0, sizeof(tc90522_config)); 2303 - memset(&info, 0, sizeof(struct i2c_board_info)); 2304 - strlcpy(info.type, "tc90522sat", I2C_NAME_SIZE); 2305 - info.addr = 0x15; 2306 - info.platform_data = &tc90522_config; 2307 - request_module("tc90522"); 2308 - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); 2309 - if (client == NULL || client->dev.driver == NULL) { 2310 - result = -ENODEV; 2311 - goto out_free; 2312 - } 2313 - dvb->i2c_client_demod = client; 2314 - if (!try_module_get(client->dev.driver->owner)) { 2315 - i2c_unregister_device(client); 2316 - result = -ENODEV; 2317 - goto out_free; 2318 - } 2319 - 2320 - /* attach tuner */ 2321 - memset(&qm1d1c0042_config, 0, 2322 - sizeof(qm1d1c0042_config)); 2323 - qm1d1c0042_config.fe = tc90522_config.fe; 2324 - qm1d1c0042_config.lpf = 1; 2325 - memset(&info, 0, sizeof(struct i2c_board_info)); 2326 - strlcpy(info.type, "qm1d1c0042", I2C_NAME_SIZE); 2327 - info.addr = 0x61; 2328 - info.platform_data = &qm1d1c0042_config; 2329 - request_module(info.type); 2330 - client = i2c_new_device(tc90522_config.tuner_i2c, 2331 - &info); 2332 - if (client == NULL || client->dev.driver == NULL) { 2333 - module_put(dvb->i2c_client_demod->dev.driver->owner); 2334 - i2c_unregister_device(dvb->i2c_client_demod); 2335 - result = -ENODEV; 2336 - goto out_free; 2337 - } 2338 - dvb->i2c_client_tuner = client; 2339 - if (!try_module_get(client->dev.driver->owner)) { 2340 - i2c_unregister_device(client); 2341 - module_put(dvb->i2c_client_demod->dev.driver->owner); 2342 - i2c_unregister_device(dvb->i2c_client_demod); 2343 - result = -ENODEV; 2344 - goto out_free; 2345 - } 2346 - dvb->fe[0] = tc90522_config.fe; 2347 - px_bcud_init(dev); 2348 - } 1645 + result = em28178_dvb_init_plex_px_bcud(dev); 1646 + if (result) 1647 + goto out_free; 2349 1648 break; 2350 1649 case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_DVB: 2351 - { 2352 - struct i2c_adapter *adapter; 2353 - struct i2c_client *client; 2354 - struct i2c_board_info info; 2355 - struct si2168_config si2168_config; 2356 - struct si2157_config si2157_config; 2357 - 2358 - /* attach demod */ 2359 - memset(&si2168_config, 0, sizeof(si2168_config)); 2360 - si2168_config.i2c_adapter = &adapter; 2361 - si2168_config.fe = &dvb->fe[0]; 2362 - si2168_config.ts_mode = SI2168_TS_SERIAL; 2363 - memset(&info, 0, sizeof(struct i2c_board_info)); 2364 - strlcpy(info.type, "si2168", I2C_NAME_SIZE); 2365 - if (dev->ts == PRIMARY_TS) 2366 - info.addr = 0x64; 2367 - else 2368 - info.addr = 0x67; 2369 - info.platform_data = &si2168_config; 2370 - request_module(info.type); 2371 - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); 2372 - if (client == NULL || client->dev.driver == NULL) { 2373 - result = -ENODEV; 2374 - goto out_free; 2375 - } 2376 - 2377 - if (!try_module_get(client->dev.driver->owner)) { 2378 - i2c_unregister_device(client); 2379 - result = -ENODEV; 2380 - goto out_free; 2381 - } 2382 - 2383 - dvb->i2c_client_demod = client; 2384 - 2385 - /* attach tuner */ 2386 - memset(&si2157_config, 0, sizeof(si2157_config)); 2387 - si2157_config.fe = dvb->fe[0]; 2388 - si2157_config.if_port = 1; 2389 - #ifdef CONFIG_MEDIA_CONTROLLER_DVB 2390 - si2157_config.mdev = dev->media_dev; 2391 - #endif 2392 - memset(&info, 0, sizeof(struct i2c_board_info)); 2393 - strlcpy(info.type, "si2157", I2C_NAME_SIZE); 2394 - if (dev->ts == PRIMARY_TS) 2395 - info.addr = 0x60; 2396 - else 2397 - info.addr = 0x63; 2398 - info.platform_data = &si2157_config; 2399 - request_module(info.type); 2400 - client = i2c_new_device(adapter, &info); 2401 - if (client == NULL || client->dev.driver == NULL) { 2402 - module_put(dvb->i2c_client_demod->dev.driver->owner); 2403 - i2c_unregister_device(dvb->i2c_client_demod); 2404 - result = -ENODEV; 2405 - goto out_free; 2406 - } 2407 - 2408 - if (!try_module_get(client->dev.driver->owner)) { 2409 - i2c_unregister_device(client); 2410 - module_put(dvb->i2c_client_demod->dev.driver->owner); 2411 - i2c_unregister_device(dvb->i2c_client_demod); 2412 - result = -ENODEV; 2413 - goto out_free; 2414 - } 2415 - 2416 - dvb->i2c_client_tuner = client; 2417 - 2418 - } 1650 + result = em28174_dvb_init_hauppauge_wintv_dualhd_dvb(dev); 1651 + if (result) 1652 + goto out_free; 2419 1653 break; 2420 1654 case EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595: 2421 - { 2422 - struct i2c_adapter *adapter; 2423 - struct i2c_client *client; 2424 - struct i2c_board_info info = {}; 2425 - struct lgdt3306a_config lgdt3306a_config; 2426 - struct si2157_config si2157_config = {}; 2427 - 2428 - /* attach demod */ 2429 - lgdt3306a_config = hauppauge_01595_lgdt3306a_config; 2430 - lgdt3306a_config.fe = &dvb->fe[0]; 2431 - lgdt3306a_config.i2c_adapter = &adapter; 2432 - strlcpy(info.type, "lgdt3306a", sizeof(info.type)); 2433 - if (dev->ts == PRIMARY_TS) 2434 - info.addr = 0x59; 2435 - else 2436 - info.addr = 0x0e; 2437 - info.platform_data = &lgdt3306a_config; 2438 - request_module(info.type); 2439 - client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], 2440 - &info); 2441 - if (client == NULL || client->dev.driver == NULL) { 2442 - result = -ENODEV; 2443 - goto out_free; 2444 - } 2445 - 2446 - if (!try_module_get(client->dev.driver->owner)) { 2447 - i2c_unregister_device(client); 2448 - result = -ENODEV; 2449 - goto out_free; 2450 - } 2451 - 2452 - dvb->i2c_client_demod = client; 2453 - 2454 - /* attach tuner */ 2455 - si2157_config.fe = dvb->fe[0]; 2456 - si2157_config.if_port = 1; 2457 - si2157_config.inversion = 1; 2458 - #ifdef CONFIG_MEDIA_CONTROLLER_DVB 2459 - si2157_config.mdev = dev->media_dev; 2460 - #endif 2461 - memset(&info, 0, sizeof(struct i2c_board_info)); 2462 - strlcpy(info.type, "si2157", sizeof(info.type)); 2463 - if (dev->ts == PRIMARY_TS) 2464 - info.addr = 0x60; 2465 - else 2466 - info.addr = 0x62; 2467 - info.platform_data = &si2157_config; 2468 - request_module(info.type); 2469 - 2470 - client = i2c_new_device(adapter, &info); 2471 - if (client == NULL || client->dev.driver == NULL) { 2472 - module_put(dvb->i2c_client_demod->dev.driver->owner); 2473 - i2c_unregister_device(dvb->i2c_client_demod); 2474 - result = -ENODEV; 2475 - goto out_free; 2476 - } 2477 - if (!try_module_get(client->dev.driver->owner)) { 2478 - i2c_unregister_device(client); 2479 - module_put(dvb->i2c_client_demod->dev.driver->owner); 2480 - i2c_unregister_device(dvb->i2c_client_demod); 2481 - result = -ENODEV; 2482 - goto out_free; 2483 - } 2484 - 2485 - dvb->i2c_client_tuner = client; 2486 - } 1655 + result = em28174_dvb_init_hauppauge_wintv_dualhd_01595(dev); 1656 + if (result) 1657 + goto out_free; 2487 1658 break; 2488 1659 default: 2489 1660 dev_err(&dev->intf->dev,