diff options
| -rw-r--r-- | drivers/media/dvb/siano/sms-cards.c | 2 | ||||
| -rw-r--r-- | drivers/media/dvb/siano/smscoreapi.c | 235 | ||||
| -rw-r--r-- | drivers/media/dvb/siano/smscoreapi.h | 55 |
3 files changed, 288 insertions, 4 deletions
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index 1a1890680349..370cf513a81a 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c | |||
| @@ -109,7 +109,7 @@ static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) | |||
| 109 | { | 109 | { |
| 110 | int lvl, ret; | 110 | int lvl, ret; |
| 111 | u32 gpio; | 111 | u32 gpio; |
| 112 | struct smscore_gpio_config gpioconfig = { | 112 | struct smscore_config_gpio gpioconfig = { |
| 113 | .direction = SMS_GPIO_DIRECTION_OUTPUT, | 113 | .direction = SMS_GPIO_DIRECTION_OUTPUT, |
| 114 | .pullupdown = SMS_GPIO_PULLUPDOWN_NONE, | 114 | .pullupdown = SMS_GPIO_PULLUPDOWN_NONE, |
| 115 | .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL, | 115 | .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL, |
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 00a1053e5f98..043368a03133 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; |
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 6e23c5f68088..03bdc94950fe 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h | |||
| @@ -549,7 +549,7 @@ struct SMSHOSTLIB_I2C_RES_ST { | |||
| 549 | }; | 549 | }; |
| 550 | 550 | ||
| 551 | 551 | ||
| 552 | struct smscore_gpio_config { | 552 | struct smscore_config_gpio { |
| 553 | #define SMS_GPIO_DIRECTION_INPUT 0 | 553 | #define SMS_GPIO_DIRECTION_INPUT 0 |
| 554 | #define SMS_GPIO_DIRECTION_OUTPUT 1 | 554 | #define SMS_GPIO_DIRECTION_OUTPUT 1 |
| 555 | u8 direction; | 555 | u8 direction; |
| @@ -575,6 +575,48 @@ struct smscore_gpio_config { | |||
| 575 | u8 outputdriving; | 575 | u8 outputdriving; |
| 576 | }; | 576 | }; |
| 577 | 577 | ||
| 578 | struct smscore_gpio_config { | ||
| 579 | #define SMS_GPIO_DIRECTION_INPUT 0 | ||
| 580 | #define SMS_GPIO_DIRECTION_OUTPUT 1 | ||
| 581 | u8 Direction; | ||
| 582 | |||
| 583 | #define SMS_GPIO_PULLUPDOWN_NONE 0 | ||
| 584 | #define SMS_GPIO_PULLUPDOWN_PULLDOWN 1 | ||
| 585 | #define SMS_GPIO_PULLUPDOWN_PULLUP 2 | ||
| 586 | #define SMS_GPIO_PULLUPDOWN_KEEPER 3 | ||
| 587 | u8 PullUpDown; | ||
| 588 | |||
| 589 | #define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL 0 | ||
| 590 | #define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1 | ||
| 591 | u8 InputCharacteristics; | ||
| 592 | |||
| 593 | #define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW 1 /* 10xx */ | ||
| 594 | #define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0 /* 10xx */ | ||
| 595 | |||
| 596 | |||
| 597 | #define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0 /* 11xx */ | ||
| 598 | #define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1 /* 11xx */ | ||
| 599 | #define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2 /* 11xx */ | ||
| 600 | #define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3 /* 11xx */ | ||
| 601 | u8 OutputSlewRate; | ||
| 602 | |||
| 603 | #define SMS_GPIO_OUTPUT_DRIVING_S_4mA 0 /* 10xx */ | ||
| 604 | #define SMS_GPIO_OUTPUT_DRIVING_S_8mA 1 /* 10xx */ | ||
| 605 | #define SMS_GPIO_OUTPUT_DRIVING_S_12mA 2 /* 10xx */ | ||
| 606 | #define SMS_GPIO_OUTPUT_DRIVING_S_16mA 3 /* 10xx */ | ||
| 607 | |||
| 608 | #define SMS_GPIO_OUTPUT_DRIVING_1_5mA 0 /* 11xx */ | ||
| 609 | #define SMS_GPIO_OUTPUT_DRIVING_2_8mA 1 /* 11xx */ | ||
| 610 | #define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */ | ||
| 611 | #define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */ | ||
| 612 | #define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */ | ||
| 613 | #define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */ | ||
| 614 | #define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */ | ||
| 615 | #undef SMS_GPIO_OUTPUT_DRIVING_16mA | ||
| 616 | #define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */ | ||
| 617 | u8 OutputDriving; | ||
| 618 | }; | ||
| 619 | |||
| 578 | extern void smscore_registry_setmode(char *devpath, int mode); | 620 | extern void smscore_registry_setmode(char *devpath, int mode); |
| 579 | extern int smscore_registry_getmode(char *devpath); | 621 | extern int smscore_registry_getmode(char *devpath); |
| 580 | 622 | ||
| @@ -616,10 +658,19 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev); | |||
| 616 | extern void smscore_putbuffer(struct smscore_device_t *coredev, | 658 | extern void smscore_putbuffer(struct smscore_device_t *coredev, |
| 617 | struct smscore_buffer_t *cb); | 659 | struct smscore_buffer_t *cb); |
| 618 | 660 | ||
| 661 | /* old GPIO managment */ | ||
| 619 | int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, | 662 | int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, |
| 620 | struct smscore_gpio_config *pinconfig); | 663 | struct smscore_config_gpio *pinconfig); |
| 621 | int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level); | 664 | int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level); |
| 622 | 665 | ||
| 666 | /* new GPIO managment */ | ||
| 667 | extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, | ||
| 668 | struct smscore_gpio_config *pGpioConfig); | ||
| 669 | extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, | ||
| 670 | u8 NewLevel); | ||
| 671 | extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum, | ||
| 672 | u8 *level); | ||
| 673 | |||
| 623 | void smscore_set_board_id(struct smscore_device_t *core, int id); | 674 | void smscore_set_board_id(struct smscore_device_t *core, int id); |
| 624 | int smscore_get_board_id(struct smscore_device_t *core); | 675 | int smscore_get_board_id(struct smscore_device_t *core); |
| 625 | 676 | ||
