diff options
author | Uri Shkolnik <uris@siano-ms.com> | 2009-05-19 10:49:19 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-16 18:14:38 -0400 |
commit | 7c4ca79f4969a5c5ffcf31a3ba01453821669ced (patch) | |
tree | 589e69aa0847c8d9d8ae79d91d11f02d12623b71 | |
parent | db9582a1e447daffec54a7172f6f824cfaed0a8e (diff) |
V4L/DVB (11885): Siano: Add new GPIO management interface
Add new GPIO management interface to replace old (buggy) one.
Keeping old interface intact for now.
Signed-off-by: Uri Shkolnik <uris@siano-ms.com>
Acked-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-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 | ||