diff options
Diffstat (limited to 'drivers/media/dvb/siano/smscoreapi.c')
-rw-r--r-- | drivers/media/dvb/siano/smscoreapi.c | 235 |
1 files changed, 234 insertions, 1 deletions
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 00a1053e5f9..043368a0313 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c | |||
@@ -1276,8 +1276,9 @@ int smsclient_sendrequest(struct smscore_client_t *client, | |||
1276 | EXPORT_SYMBOL_GPL(smsclient_sendrequest); | 1276 | EXPORT_SYMBOL_GPL(smsclient_sendrequest); |
1277 | 1277 | ||
1278 | 1278 | ||
1279 | /* old GPIO managments implementation */ | ||
1279 | int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, | 1280 | int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, |
1280 | struct smscore_gpio_config *pinconfig) | 1281 | struct smscore_config_gpio *pinconfig) |
1281 | { | 1282 | { |
1282 | struct { | 1283 | struct { |
1283 | struct SmsMsgHdr_ST hdr; | 1284 | struct SmsMsgHdr_ST hdr; |
@@ -1346,6 +1347,238 @@ int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level) | |||
1346 | &msg, sizeof(msg)); | 1347 | &msg, sizeof(msg)); |
1347 | } | 1348 | } |
1348 | 1349 | ||
1350 | /* new GPIO managment implementation */ | ||
1351 | static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum, | ||
1352 | u32 *pGroupNum, u32 *pGroupCfg) { | ||
1353 | |||
1354 | *pGroupCfg = 1; | ||
1355 | |||
1356 | if (PinNum >= 0 && PinNum <= 1) { | ||
1357 | *pTranslatedPinNum = 0; | ||
1358 | *pGroupNum = 9; | ||
1359 | *pGroupCfg = 2; | ||
1360 | } else if (PinNum >= 2 && PinNum <= 6) { | ||
1361 | *pTranslatedPinNum = 2; | ||
1362 | *pGroupNum = 0; | ||
1363 | *pGroupCfg = 2; | ||
1364 | } else if (PinNum >= 7 && PinNum <= 11) { | ||
1365 | *pTranslatedPinNum = 7; | ||
1366 | *pGroupNum = 1; | ||
1367 | } else if (PinNum >= 12 && PinNum <= 15) { | ||
1368 | *pTranslatedPinNum = 12; | ||
1369 | *pGroupNum = 2; | ||
1370 | *pGroupCfg = 3; | ||
1371 | } else if (PinNum == 16) { | ||
1372 | *pTranslatedPinNum = 16; | ||
1373 | *pGroupNum = 23; | ||
1374 | } else if (PinNum >= 17 && PinNum <= 24) { | ||
1375 | *pTranslatedPinNum = 17; | ||
1376 | *pGroupNum = 3; | ||
1377 | } else if (PinNum == 25) { | ||
1378 | *pTranslatedPinNum = 25; | ||
1379 | *pGroupNum = 6; | ||
1380 | } else if (PinNum >= 26 && PinNum <= 28) { | ||
1381 | *pTranslatedPinNum = 26; | ||
1382 | *pGroupNum = 4; | ||
1383 | } else if (PinNum == 29) { | ||
1384 | *pTranslatedPinNum = 29; | ||
1385 | *pGroupNum = 5; | ||
1386 | *pGroupCfg = 2; | ||
1387 | } else if (PinNum == 30) { | ||
1388 | *pTranslatedPinNum = 30; | ||
1389 | *pGroupNum = 8; | ||
1390 | } else if (PinNum == 31) { | ||
1391 | *pTranslatedPinNum = 31; | ||
1392 | *pGroupNum = 17; | ||
1393 | } else | ||
1394 | return -1; | ||
1395 | |||
1396 | *pGroupCfg <<= 24; | ||
1397 | |||
1398 | return 0; | ||
1399 | } | ||
1400 | |||
1401 | int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, | ||
1402 | struct smscore_gpio_config *pGpioConfig) { | ||
1403 | |||
1404 | u32 totalLen; | ||
1405 | u32 TranslatedPinNum; | ||
1406 | u32 GroupNum; | ||
1407 | u32 ElectricChar; | ||
1408 | u32 groupCfg; | ||
1409 | void *buffer; | ||
1410 | int rc; | ||
1411 | |||
1412 | struct SetGpioMsg { | ||
1413 | struct SmsMsgHdr_ST xMsgHeader; | ||
1414 | u32 msgData[6]; | ||
1415 | } *pMsg; | ||
1416 | |||
1417 | |||
1418 | if (PinNum > MAX_GPIO_PIN_NUMBER) | ||
1419 | return -EINVAL; | ||
1420 | |||
1421 | if (pGpioConfig == NULL) | ||
1422 | return -EINVAL; | ||
1423 | |||
1424 | totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6); | ||
1425 | |||
1426 | buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, | ||
1427 | GFP_KERNEL | GFP_DMA); | ||
1428 | if (!buffer) | ||
1429 | return -ENOMEM; | ||
1430 | |||
1431 | pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); | ||
1432 | |||
1433 | pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; | ||
1434 | pMsg->xMsgHeader.msgDstId = HIF_TASK; | ||
1435 | pMsg->xMsgHeader.msgFlags = 0; | ||
1436 | pMsg->xMsgHeader.msgLength = (u16) totalLen; | ||
1437 | pMsg->msgData[0] = PinNum; | ||
1438 | |||
1439 | if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) { | ||
1440 | pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ; | ||
1441 | if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum, | ||
1442 | &groupCfg) != 0) | ||
1443 | return -EINVAL; | ||
1444 | |||
1445 | pMsg->msgData[1] = TranslatedPinNum; | ||
1446 | pMsg->msgData[2] = GroupNum; | ||
1447 | ElectricChar = (pGpioConfig->PullUpDown) | ||
1448 | | (pGpioConfig->InputCharacteristics << 2) | ||
1449 | | (pGpioConfig->OutputSlewRate << 3) | ||
1450 | | (pGpioConfig->OutputDriving << 4); | ||
1451 | pMsg->msgData[3] = ElectricChar; | ||
1452 | pMsg->msgData[4] = pGpioConfig->Direction; | ||
1453 | pMsg->msgData[5] = groupCfg; | ||
1454 | } else { | ||
1455 | pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ; | ||
1456 | pMsg->msgData[1] = pGpioConfig->PullUpDown; | ||
1457 | pMsg->msgData[2] = pGpioConfig->OutputSlewRate; | ||
1458 | pMsg->msgData[3] = pGpioConfig->OutputDriving; | ||
1459 | pMsg->msgData[4] = pGpioConfig->Direction; | ||
1460 | pMsg->msgData[5] = 0; | ||
1461 | } | ||
1462 | |||
1463 | smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); | ||
1464 | rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, | ||
1465 | &coredev->gpio_configuration_done); | ||
1466 | |||
1467 | if (rc != 0) { | ||
1468 | if (rc == -ETIME) | ||
1469 | sms_err("smscore_gpio_configure timeout"); | ||
1470 | else | ||
1471 | sms_err("smscore_gpio_configure error"); | ||
1472 | } | ||
1473 | kfree(buffer); | ||
1474 | |||
1475 | return rc; | ||
1476 | } | ||
1477 | |||
1478 | int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, | ||
1479 | u8 NewLevel) { | ||
1480 | |||
1481 | u32 totalLen; | ||
1482 | int rc; | ||
1483 | void *buffer; | ||
1484 | |||
1485 | struct SetGpioMsg { | ||
1486 | struct SmsMsgHdr_ST xMsgHeader; | ||
1487 | u32 msgData[3]; /* keep it 3 ! */ | ||
1488 | } *pMsg; | ||
1489 | |||
1490 | if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) || | ||
1491 | (PinNum > MAX_GPIO_PIN_NUMBER)) | ||
1492 | return -EINVAL; | ||
1493 | |||
1494 | totalLen = sizeof(struct SmsMsgHdr_ST) + | ||
1495 | (3 * sizeof(u32)); /* keep it 3 ! */ | ||
1496 | |||
1497 | buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, | ||
1498 | GFP_KERNEL | GFP_DMA); | ||
1499 | if (!buffer) | ||
1500 | return -ENOMEM; | ||
1501 | |||
1502 | pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); | ||
1503 | |||
1504 | pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; | ||
1505 | pMsg->xMsgHeader.msgDstId = HIF_TASK; | ||
1506 | pMsg->xMsgHeader.msgFlags = 0; | ||
1507 | pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ; | ||
1508 | pMsg->xMsgHeader.msgLength = (u16) totalLen; | ||
1509 | pMsg->msgData[0] = PinNum; | ||
1510 | pMsg->msgData[1] = NewLevel; | ||
1511 | |||
1512 | /* Send message to SMS */ | ||
1513 | smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); | ||
1514 | rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, | ||
1515 | &coredev->gpio_set_level_done); | ||
1516 | |||
1517 | if (rc != 0) { | ||
1518 | if (rc == -ETIME) | ||
1519 | sms_err("smscore_gpio_set_level timeout"); | ||
1520 | else | ||
1521 | sms_err("smscore_gpio_set_level error"); | ||
1522 | } | ||
1523 | kfree(buffer); | ||
1524 | |||
1525 | return rc; | ||
1526 | } | ||
1527 | |||
1528 | int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum, | ||
1529 | u8 *level) { | ||
1530 | |||
1531 | u32 totalLen; | ||
1532 | int rc; | ||
1533 | void *buffer; | ||
1534 | |||
1535 | struct SetGpioMsg { | ||
1536 | struct SmsMsgHdr_ST xMsgHeader; | ||
1537 | u32 msgData[2]; | ||
1538 | } *pMsg; | ||
1539 | |||
1540 | |||
1541 | if (PinNum > MAX_GPIO_PIN_NUMBER) | ||
1542 | return -EINVAL; | ||
1543 | |||
1544 | totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32)); | ||
1545 | |||
1546 | buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, | ||
1547 | GFP_KERNEL | GFP_DMA); | ||
1548 | if (!buffer) | ||
1549 | return -ENOMEM; | ||
1550 | |||
1551 | pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); | ||
1552 | |||
1553 | pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; | ||
1554 | pMsg->xMsgHeader.msgDstId = HIF_TASK; | ||
1555 | pMsg->xMsgHeader.msgFlags = 0; | ||
1556 | pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ; | ||
1557 | pMsg->xMsgHeader.msgLength = (u16) totalLen; | ||
1558 | pMsg->msgData[0] = PinNum; | ||
1559 | pMsg->msgData[1] = 0; | ||
1560 | |||
1561 | /* Send message to SMS */ | ||
1562 | smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); | ||
1563 | rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, | ||
1564 | &coredev->gpio_get_level_done); | ||
1565 | |||
1566 | if (rc != 0) { | ||
1567 | if (rc == -ETIME) | ||
1568 | sms_err("smscore_gpio_get_level timeout"); | ||
1569 | else | ||
1570 | sms_err("smscore_gpio_get_level error"); | ||
1571 | } | ||
1572 | kfree(buffer); | ||
1573 | |||
1574 | /* Its a race between other gpio_get_level() and the copy of the single | ||
1575 | * global 'coredev->gpio_get_res' to the function's variable 'level' | ||
1576 | */ | ||
1577 | *level = coredev->gpio_get_res; | ||
1578 | |||
1579 | return rc; | ||
1580 | } | ||
1581 | |||
1349 | static int __init smscore_module_init(void) | 1582 | static int __init smscore_module_init(void) |
1350 | { | 1583 | { |
1351 | int rc = 0; | 1584 | int rc = 0; |