On Tue, May 19, 2009 at 10:49 AM, Uri Shkolnik <urishk@xxxxxxxxx> wrote: > > # HG changeset patch > # User Uri Shkolnik <uris@xxxxxxxxxxxx> > # Date 1242744570 -10800 > # Node ID 749c11a362a9fad1992809007247d5c76c35bfc9 > # Parent 08e292f80f37496d8d4b43a542f518196eaa4dc0 > [09051_43] Siano: Add new GPIO management interface > > From: Uri Shkolnik <uris@xxxxxxxxxxxx> > > Add new GPIO management interface to replace old (buggy) one. > Keeping old interface intact for now. > > Priority: normal > > Signed-off-by: Uri Shkolnik <uris@xxxxxxxxxxxx> > > diff -r 08e292f80f37 -r 749c11a362a9 linux/drivers/media/dvb/siano/sms-cards.c > --- a/linux/drivers/media/dvb/siano/sms-cards.c Tue May 19 16:30:40 2009 +0300 > +++ b/linux/drivers/media/dvb/siano/sms-cards.c Tue May 19 17:49:30 2009 +0300 > @@ -109,7 +109,7 @@ static int sms_set_gpio(struct smscore_d > { > 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, > diff -r 08e292f80f37 -r 749c11a362a9 linux/drivers/media/dvb/siano/smscoreapi.c > --- a/linux/drivers/media/dvb/siano/smscoreapi.c Tue May 19 16:30:40 2009 +0300 > +++ b/linux/drivers/media/dvb/siano/smscoreapi.c Tue May 19 17:49:30 2009 +0300 > @@ -1331,8 +1331,9 @@ static int smscore_map_common_buffer(str > } > #endif > > +/* 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; > @@ -1399,6 +1400,238 @@ int smscore_set_gpio(struct smscore_devi > > return coredev->sendrequest_handler(coredev->context, > &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) > diff -r 08e292f80f37 -r 749c11a362a9 linux/drivers/media/dvb/siano/smscoreapi.h > --- a/linux/drivers/media/dvb/siano/smscoreapi.h Tue May 19 16:30:40 2009 +0300 > +++ b/linux/drivers/media/dvb/siano/smscoreapi.h Tue May 19 17:49:30 2009 +0300 > @@ -550,7 +550,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; > @@ -574,6 +574,48 @@ struct smscore_gpio_config { > #define SMS_GPIO_OUTPUTDRIVING_12mA 2 > #define SMS_GPIO_OUTPUTDRIVING_16mA 3 > 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); > @@ -619,9 +661,18 @@ extern void smscore_putbuffer(struct sms > 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); > > > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > Mauro, I am OK with this changeset, since the old GPIO functions were left intact. I haven't actually TESTED this patch, but I will do so after it's merged. After Uri is done with his changes, I will cleanup the Hauppauge code for GPIO handling, to remove the duplicated functionality. It would have been cleaner to simply add the "wait" flag to the new gpio function, but I cant tell Uri what to do -- this is OK for now. Acked-by: Michael Krufky <mkrufky@xxxxxxxxxxx> -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html