aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/siano/smscoreapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/siano/smscoreapi.c')
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c235
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,
1276EXPORT_SYMBOL_GPL(smsclient_sendrequest); 1276EXPORT_SYMBOL_GPL(smsclient_sendrequest);
1277 1277
1278 1278
1279/* old GPIO managments implementation */
1279int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, 1280int 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 */
1351static 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
1401int 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
1478int 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
1528int 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
1349static int __init smscore_module_init(void) 1582static int __init smscore_module_init(void)
1350{ 1583{
1351 int rc = 0; 1584 int rc = 0;