aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUri Shkolnik <uris@siano-ms.com>2009-05-19 10:49:19 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-06-16 18:14:38 -0400
commit7c4ca79f4969a5c5ffcf31a3ba01453821669ced (patch)
tree589e69aa0847c8d9d8ae79d91d11f02d12623b71
parentdb9582a1e447daffec54a7172f6f824cfaed0a8e (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.c2
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c235
-rw-r--r--drivers/media/dvb/siano/smscoreapi.h55
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,
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;
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
552struct smscore_gpio_config { 552struct 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
578struct 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
578extern void smscore_registry_setmode(char *devpath, int mode); 620extern void smscore_registry_setmode(char *devpath, int mode);
579extern int smscore_registry_getmode(char *devpath); 621extern int smscore_registry_getmode(char *devpath);
580 622
@@ -616,10 +658,19 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
616extern void smscore_putbuffer(struct smscore_device_t *coredev, 658extern 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 */
619int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, 662int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
620 struct smscore_gpio_config *pinconfig); 663 struct smscore_config_gpio *pinconfig);
621int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level); 664int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level);
622 665
666/* new GPIO managment */
667extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
668 struct smscore_gpio_config *pGpioConfig);
669extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
670 u8 NewLevel);
671extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
672 u8 *level);
673
623void smscore_set_board_id(struct smscore_device_t *core, int id); 674void smscore_set_board_id(struct smscore_device_t *core, int id);
624int smscore_get_board_id(struct smscore_device_t *core); 675int smscore_get_board_id(struct smscore_device_t *core);
625 676