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>
This commit is contained in:
Uri Shkolnik 2009-05-19 11:49:19 -03:00 коммит произвёл Mauro Carvalho Chehab
Родитель db9582a1e4
Коммит 7c4ca79f49
3 изменённых файлов: 288 добавлений и 4 удалений

Просмотреть файл

@ -109,7 +109,7 @@ static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
{
int lvl, ret;
u32 gpio;
struct smscore_gpio_config gpioconfig = {
struct smscore_config_gpio gpioconfig = {
.direction = SMS_GPIO_DIRECTION_OUTPUT,
.pullupdown = SMS_GPIO_PULLUPDOWN_NONE,
.inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,

Просмотреть файл

@ -1276,8 +1276,9 @@ int smsclient_sendrequest(struct smscore_client_t *client,
EXPORT_SYMBOL_GPL(smsclient_sendrequest);
/* old GPIO managments implementation */
int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
struct smscore_gpio_config *pinconfig)
struct smscore_config_gpio *pinconfig)
{
struct {
struct SmsMsgHdr_ST hdr;
@ -1346,6 +1347,238 @@ int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
&msg, sizeof(msg));
}
/* new GPIO managment implementation */
static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
u32 *pGroupNum, u32 *pGroupCfg) {
*pGroupCfg = 1;
if (PinNum >= 0 && PinNum <= 1) {
*pTranslatedPinNum = 0;
*pGroupNum = 9;
*pGroupCfg = 2;
} else if (PinNum >= 2 && PinNum <= 6) {
*pTranslatedPinNum = 2;
*pGroupNum = 0;
*pGroupCfg = 2;
} else if (PinNum >= 7 && PinNum <= 11) {
*pTranslatedPinNum = 7;
*pGroupNum = 1;
} else if (PinNum >= 12 && PinNum <= 15) {
*pTranslatedPinNum = 12;
*pGroupNum = 2;
*pGroupCfg = 3;
} else if (PinNum == 16) {
*pTranslatedPinNum = 16;
*pGroupNum = 23;
} else if (PinNum >= 17 && PinNum <= 24) {
*pTranslatedPinNum = 17;
*pGroupNum = 3;
} else if (PinNum == 25) {
*pTranslatedPinNum = 25;
*pGroupNum = 6;
} else if (PinNum >= 26 && PinNum <= 28) {
*pTranslatedPinNum = 26;
*pGroupNum = 4;
} else if (PinNum == 29) {
*pTranslatedPinNum = 29;
*pGroupNum = 5;
*pGroupCfg = 2;
} else if (PinNum == 30) {
*pTranslatedPinNum = 30;
*pGroupNum = 8;
} else if (PinNum == 31) {
*pTranslatedPinNum = 31;
*pGroupNum = 17;
} else
return -1;
*pGroupCfg <<= 24;
return 0;
}
int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
struct smscore_gpio_config *pGpioConfig) {
u32 totalLen;
u32 TranslatedPinNum;
u32 GroupNum;
u32 ElectricChar;
u32 groupCfg;
void *buffer;
int rc;
struct SetGpioMsg {
struct SmsMsgHdr_ST xMsgHeader;
u32 msgData[6];
} *pMsg;
if (PinNum > MAX_GPIO_PIN_NUMBER)
return -EINVAL;
if (pGpioConfig == NULL)
return -EINVAL;
totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6);
buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
GFP_KERNEL | GFP_DMA);
if (!buffer)
return -ENOMEM;
pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
pMsg->xMsgHeader.msgDstId = HIF_TASK;
pMsg->xMsgHeader.msgFlags = 0;
pMsg->xMsgHeader.msgLength = (u16) totalLen;
pMsg->msgData[0] = PinNum;
if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
&groupCfg) != 0)
return -EINVAL;
pMsg->msgData[1] = TranslatedPinNum;
pMsg->msgData[2] = GroupNum;
ElectricChar = (pGpioConfig->PullUpDown)
| (pGpioConfig->InputCharacteristics << 2)
| (pGpioConfig->OutputSlewRate << 3)
| (pGpioConfig->OutputDriving << 4);
pMsg->msgData[3] = ElectricChar;
pMsg->msgData[4] = pGpioConfig->Direction;
pMsg->msgData[5] = groupCfg;
} else {
pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
pMsg->msgData[1] = pGpioConfig->PullUpDown;
pMsg->msgData[2] = pGpioConfig->OutputSlewRate;
pMsg->msgData[3] = pGpioConfig->OutputDriving;
pMsg->msgData[4] = pGpioConfig->Direction;
pMsg->msgData[5] = 0;
}
smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
&coredev->gpio_configuration_done);
if (rc != 0) {
if (rc == -ETIME)
sms_err("smscore_gpio_configure timeout");
else
sms_err("smscore_gpio_configure error");
}
kfree(buffer);
return rc;
}
int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
u8 NewLevel) {
u32 totalLen;
int rc;
void *buffer;
struct SetGpioMsg {
struct SmsMsgHdr_ST xMsgHeader;
u32 msgData[3]; /* keep it 3 ! */
} *pMsg;
if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) ||
(PinNum > MAX_GPIO_PIN_NUMBER))
return -EINVAL;
totalLen = sizeof(struct SmsMsgHdr_ST) +
(3 * sizeof(u32)); /* keep it 3 ! */
buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
GFP_KERNEL | GFP_DMA);
if (!buffer)
return -ENOMEM;
pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
pMsg->xMsgHeader.msgDstId = HIF_TASK;
pMsg->xMsgHeader.msgFlags = 0;
pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
pMsg->xMsgHeader.msgLength = (u16) totalLen;
pMsg->msgData[0] = PinNum;
pMsg->msgData[1] = NewLevel;
/* Send message to SMS */
smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
&coredev->gpio_set_level_done);
if (rc != 0) {
if (rc == -ETIME)
sms_err("smscore_gpio_set_level timeout");
else
sms_err("smscore_gpio_set_level error");
}
kfree(buffer);
return rc;
}
int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
u8 *level) {
u32 totalLen;
int rc;
void *buffer;
struct SetGpioMsg {
struct SmsMsgHdr_ST xMsgHeader;
u32 msgData[2];
} *pMsg;
if (PinNum > MAX_GPIO_PIN_NUMBER)
return -EINVAL;
totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32));
buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
GFP_KERNEL | GFP_DMA);
if (!buffer)
return -ENOMEM;
pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
pMsg->xMsgHeader.msgDstId = HIF_TASK;
pMsg->xMsgHeader.msgFlags = 0;
pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
pMsg->xMsgHeader.msgLength = (u16) totalLen;
pMsg->msgData[0] = PinNum;
pMsg->msgData[1] = 0;
/* Send message to SMS */
smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
&coredev->gpio_get_level_done);
if (rc != 0) {
if (rc == -ETIME)
sms_err("smscore_gpio_get_level timeout");
else
sms_err("smscore_gpio_get_level error");
}
kfree(buffer);
/* Its a race between other gpio_get_level() and the copy of the single
* global 'coredev->gpio_get_res' to the function's variable 'level'
*/
*level = coredev->gpio_get_res;
return rc;
}
static int __init smscore_module_init(void)
{
int rc = 0;

Просмотреть файл

@ -549,7 +549,7 @@ struct SMSHOSTLIB_I2C_RES_ST {
};
struct smscore_gpio_config {
struct smscore_config_gpio {
#define SMS_GPIO_DIRECTION_INPUT 0
#define SMS_GPIO_DIRECTION_OUTPUT 1
u8 direction;
@ -575,6 +575,48 @@ struct smscore_gpio_config {
u8 outputdriving;
};
struct smscore_gpio_config {
#define SMS_GPIO_DIRECTION_INPUT 0
#define SMS_GPIO_DIRECTION_OUTPUT 1
u8 Direction;
#define SMS_GPIO_PULLUPDOWN_NONE 0
#define SMS_GPIO_PULLUPDOWN_PULLDOWN 1
#define SMS_GPIO_PULLUPDOWN_PULLUP 2
#define SMS_GPIO_PULLUPDOWN_KEEPER 3
u8 PullUpDown;
#define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL 0
#define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1
u8 InputCharacteristics;
#define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW 1 /* 10xx */
#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0 /* 10xx */
#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0 /* 11xx */
#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1 /* 11xx */
#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2 /* 11xx */
#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3 /* 11xx */
u8 OutputSlewRate;
#define SMS_GPIO_OUTPUT_DRIVING_S_4mA 0 /* 10xx */
#define SMS_GPIO_OUTPUT_DRIVING_S_8mA 1 /* 10xx */
#define SMS_GPIO_OUTPUT_DRIVING_S_12mA 2 /* 10xx */
#define SMS_GPIO_OUTPUT_DRIVING_S_16mA 3 /* 10xx */
#define SMS_GPIO_OUTPUT_DRIVING_1_5mA 0 /* 11xx */
#define SMS_GPIO_OUTPUT_DRIVING_2_8mA 1 /* 11xx */
#define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */
#define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */
#define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */
#define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */
#define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */
#undef SMS_GPIO_OUTPUT_DRIVING_16mA
#define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */
u8 OutputDriving;
};
extern void smscore_registry_setmode(char *devpath, int mode);
extern int smscore_registry_getmode(char *devpath);
@ -616,10 +658,19 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
extern void smscore_putbuffer(struct smscore_device_t *coredev,
struct smscore_buffer_t *cb);
/* old GPIO managment */
int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
struct smscore_gpio_config *pinconfig);
struct smscore_config_gpio *pinconfig);
int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level);
/* new GPIO managment */
extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
struct smscore_gpio_config *pGpioConfig);
extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
u8 NewLevel);
extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
u8 *level);
void smscore_set_board_id(struct smscore_device_t *core, int id);
int smscore_get_board_id(struct smscore_device_t *core);