[PATCH 16/25] UBUNTU hardy-lum lpia branch sync
Steve Conklin
sconklin at canonical.com
Tue Mar 10 19:34:07 UTC 2009
>From dc3ced1b0f2bc1b45b8aa1f0d9554f440f19e8d2 Mon Sep 17 00:00:00 2001
From: Uri Shkolnik <uris at siano-ms.com>
Date: Fri, 6 Mar 2009 11:58:07 -0500
Subject: [PATCH] UBUNTU: sms1xxx: update GPIO functionality to support all devices
OriginalAuthor: Uri Shkolnik <uris at siano-ms.com>
Update the GPIO functionality to work on all device types.
Add a "wait" parameter to smscore_gpio_configure and smscore_gpio_set_level to
determine whether to wait for the firmware's response to the gpio command
before returning control to the caller.
Signed-off-by: Uri Shkolnik <uris at siano-ms.com>
Signed-off-by: Michael Krufky <mkrufky at linuxtv.org>
---
ubuntu/media/sms1xxx/sms-cards.c | 12 +-
ubuntu/media/sms1xxx/smscoreapi.c | 225 +++++++++++++++++++++++++++++++------
ubuntu/media/sms1xxx/smscoreapi.h | 33 ++++--
3 files changed, 219 insertions(+), 51 deletions(-)
diff --git a/ubuntu/media/sms1xxx/sms-cards.c b/ubuntu/media/sms1xxx/sms-cards.c
index bb6c0fb..b7ee193 100644
--- a/ubuntu/media/sms1xxx/sms-cards.c
+++ b/ubuntu/media/sms1xxx/sms-cards.c
@@ -84,19 +84,21 @@ EXPORT_SYMBOL_GPL(sms_get_board);
static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
{
- int lvl, ret;
- u32 gpio;
+ u8 gpio, lvl;
+ int ret;
struct smscore_gpio_config gpioconfig = {
.direction = SMS_GPIO_DIRECTION_OUTPUT,
.pullupdown = SMS_GPIO_PULLUPDOWN_NONE,
.inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,
- .outputslewrate = SMS_GPIO_OUTPUTSLEWRATE_FAST,
+ .outputslewrate = SMS_GPIO_OUTPUTSLEWRATE_0_45_V_NS,
.outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA,
};
if (pin == 0)
return -EINVAL;
+ sms_debug("pin %x, enable %x", pin, enable);
+
if (pin < 0) {
/* inverted gpio */
gpio = pin * -1;
@@ -106,11 +108,11 @@ static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
lvl = enable ? 1 : 0;
}
- ret = smscore_configure_gpio(coredev, gpio, &gpioconfig);
+ ret = smscore_gpio_configure(coredev, gpio, &gpioconfig, 0);
if (ret < 0)
return ret;
- return smscore_set_gpio(coredev, gpio, lvl);
+ return smscore_gpio_set_level(coredev, gpio, lvl, 0);
}
int sms_board_setup(struct smscore_device_t *coredev)
diff --git a/ubuntu/media/sms1xxx/smscoreapi.c b/ubuntu/media/sms1xxx/smscoreapi.c
index eeba342..dbf3de8 100644
--- a/ubuntu/media/sms1xxx/smscoreapi.c
+++ b/ubuntu/media/sms1xxx/smscoreapi.c
@@ -93,6 +93,10 @@ struct smscore_device_t {
struct completion version_ex_done, data_download_done, trigger_done;
struct completion init_device_done, reload_start_done, resume_done;
+ struct completion gpio_configuration_done, gpio_set_level_done;
+ struct completion gpio_get_level_done;
+
+ int gpio_get_res;
int board_id;
int led_state;
@@ -377,6 +381,9 @@ int smscore_register_device(struct smsdevice_params_t *params,
init_completion(&dev->init_device_done);
init_completion(&dev->reload_start_done);
init_completion(&dev->resume_done);
+ init_completion(&dev->gpio_configuration_done);
+ init_completion(&dev->gpio_set_level_done);
+ init_completion(&dev->gpio_get_level_done);
/* alloc common buffer */
dev->common_buffer_size = params->buffer_size * params->num_buffers;
@@ -996,6 +1003,23 @@ void smscore_onresponse(struct smscore_device_t *coredev,
case MSG_SMS_SLEEP_RESUME_COMP_IND:
complete(&coredev->resume_done);
break;
+ case MSG_SMS_GPIO_CONFIG_EX_RES:
+ sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES");
+ complete(&coredev->gpio_configuration_done);
+ break;
+ case MSG_SMS_GPIO_SET_LEVEL_RES:
+ sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES");
+ complete(&coredev->gpio_set_level_done);
+ break;
+ case MSG_SMS_GPIO_GET_LEVEL_RES:
+ {
+ u32 *msgdata = (u32 *) phdr;
+ coredev->gpio_get_res = msgdata[1];
+ sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d",
+ coredev->gpio_get_res);
+ complete(&coredev->gpio_get_level_done);
+ break;
+ }
default:
#if 0
sms_info("no client (%p) or error (%d), "
@@ -1251,62 +1275,134 @@ static int smscore_map_common_buffer(struct smscore_device_t *coredev,
}
#endif
-int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
- struct smscore_gpio_config *pinconfig)
+static int get_gpio_pin_params(u32 pin, u32 *translatedpin,
+ u32 *groupnum, u32 *groupcfg)
+{
+ *groupcfg = 1;
+
+ if (pin >= 0 && pin <= 1) {
+ *translatedpin = 0;
+ *groupnum = 9;
+ *groupcfg = 2;
+ } else if (pin >= 2 && pin <= 6) {
+ *translatedpin = 2;
+ *groupnum = 0;
+ *groupcfg = 2;
+ } else if (pin >= 7 && pin <= 11) {
+ *translatedpin = 7;
+ *groupnum = 1;
+ } else if (pin >= 12 && pin <= 15) {
+ *translatedpin = 12;
+ *groupnum = 2;
+ *groupcfg = 3;
+ } else if (pin == 16) {
+ *translatedpin = 16;
+ *groupnum = 23;
+ } else if (pin >= 17 && pin <= 24) {
+ *translatedpin = 17;
+ *groupnum = 3;
+ } else if (pin == 25) {
+ *translatedpin = 25;
+ *groupnum = 6;
+ } else if (pin >= 26 && pin <= 28) {
+ *translatedpin = 26;
+ *groupnum = 4;
+ } else if (pin == 29) {
+ *translatedpin = 29;
+ *groupnum = 5;
+ *groupcfg = 2;
+ } else if (pin == 30) {
+ *translatedpin = 30;
+ *groupnum = 8;
+ } else if (pin == 31) {
+ *translatedpin = 31;
+ *groupnum = 17;
+ } else
+ return -1;
+
+ *groupcfg <<= 24;
+
+ return 0;
+}
+
+int smscore_gpio_configure(struct smscore_device_t *coredev, u8 pin,
+ struct smscore_gpio_config *gpioconfig, int wait)
{
+ int rc;
+
struct {
struct SmsMsgHdr_ST hdr;
u32 data[6];
} msg;
- if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
- msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
- msg.hdr.msgDstId = HIF_TASK;
- msg.hdr.msgFlags = 0;
- msg.hdr.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
- msg.hdr.msgLength = sizeof(msg);
- msg.data[0] = pin;
- msg.data[1] = pinconfig->pullupdown;
+ if ((pin > MAX_GPIO_PIN_NUMBER) || (gpioconfig == NULL))
+ return -EINVAL;
+
+ msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+ msg.hdr.msgDstId = HIF_TASK;
+ msg.hdr.msgFlags = 0;
+ msg.hdr.msgLength = sizeof(msg);
+ msg.data[0] = pin;
- /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */
- msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0;
+ if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
+ u32 translatedpinnum;
+ u32 groupnum;
+ u32 groupcfg;
- switch (pinconfig->outputdriving) {
- case SMS_GPIO_OUTPUTDRIVING_16mA:
- msg.data[3] = 7; /* Nova - 16mA */
- break;
- case SMS_GPIO_OUTPUTDRIVING_12mA:
- msg.data[3] = 5; /* Nova - 11mA */
- break;
- case SMS_GPIO_OUTPUTDRIVING_8mA:
- msg.data[3] = 3; /* Nova - 7mA */
- break;
- case SMS_GPIO_OUTPUTDRIVING_4mA:
- default:
- msg.data[3] = 2; /* Nova - 4mA */
- break;
- }
+ msg.hdr.msgType = MSG_SMS_GPIO_CONFIG_REQ;
+ if (get_gpio_pin_params(pin, &translatedpinnum, &groupnum,
+ &groupcfg) != 0)
+ return -EINVAL;
- msg.data[4] = pinconfig->direction;
+ msg.data[1] = translatedpinnum;
+ msg.data[2] = groupnum;
+ msg.data[3] = (gpioconfig->pullupdown) |
+ (gpioconfig->inputcharacteristics << 2) |
+ (gpioconfig->outputslewrate << 3) |
+ (gpioconfig->outputdriving << 4);
+ msg.data[4] = gpioconfig->direction;
+ msg.data[5] = groupcfg;
+ } else {
+ msg.hdr.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
+ msg.data[1] = gpioconfig->pullupdown;
+ msg.data[2] = gpioconfig->outputslewrate;
+ msg.data[3] = gpioconfig->outputdriving;
+ msg.data[4] = gpioconfig->direction;
msg.data[5] = 0;
- } else /* TODO: SMS_DEVICE_FAMILY1 */
- return -EINVAL;
+ }
+
+ if (wait) {
+ rc = smscore_sendrequest_and_wait(coredev, &msg, sizeof(msg),
+ &coredev->gpio_configuration_done);
+ if (rc != 0) {
+ if (rc == -ETIME)
+ sms_err("smscore_gpio_configure timeout");
+ else
+ sms_err("smscore_gpio_configure error");
+ }
+ } else
+ rc = coredev->sendrequest_handler(coredev->context,
+ &msg, sizeof(msg));
- return coredev->sendrequest_handler(coredev->context,
- &msg, sizeof(msg));
+ return rc;
}
-int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
+int smscore_gpio_set_level(struct smscore_device_t *coredev,
+ u8 pin, u8 level, int wait)
{
+ int rc;
+
struct {
struct SmsMsgHdr_ST hdr;
u32 data[3];
} msg;
- if (pin > MAX_GPIO_PIN_NUMBER)
+ if ((level > 1) || (pin > MAX_GPIO_PIN_NUMBER))
return -EINVAL;
+ sms_debug("pin %x level %x", pin, level);
+
msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
msg.hdr.msgDstId = HIF_TASK;
msg.hdr.msgFlags = 0;
@@ -1314,11 +1410,66 @@ int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
msg.hdr.msgLength = sizeof(msg);
msg.data[0] = pin;
- msg.data[1] = level ? 1 : 0;
+ msg.data[1] = level;
msg.data[2] = 0;
- return coredev->sendrequest_handler(coredev->context,
- &msg, sizeof(msg));
+ /* Sent message to SMS */
+ if (wait) {
+ rc = smscore_sendrequest_and_wait(coredev, &msg, sizeof(msg),
+ &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");
+ }
+ } else
+ rc = coredev->sendrequest_handler(coredev->context,
+ &msg, sizeof(msg));
+
+ return rc;
+}
+
+int smscore_gpio_get_level(struct smscore_device_t *coredev,
+ u8 pin, u8 *level)
+{
+ int rc;
+
+ struct {
+ struct SmsMsgHdr_ST hdr;
+ u32 data[2];
+ } msg;
+
+
+ if (pin > MAX_GPIO_PIN_NUMBER)
+ return -EINVAL;
+
+ msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
+ msg.hdr.msgDstId = HIF_TASK;
+ msg.hdr.msgFlags = 0;
+ msg.hdr.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
+ msg.hdr.msgLength = sizeof(msg);
+
+ msg.data[0] = pin;
+ msg.data[1] = 0;
+
+ /* Sent message to SMS */
+ rc = smscore_sendrequest_and_wait(coredev, &msg, sizeof(msg),
+ &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");
+ }
+
+ /* 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 --git a/ubuntu/media/sms1xxx/smscoreapi.h b/ubuntu/media/sms1xxx/smscoreapi.h
index 06d87ff..d944b51 100644
--- a/ubuntu/media/sms1xxx/smscoreapi.h
+++ b/ubuntu/media/sms1xxx/smscoreapi.h
@@ -527,14 +527,28 @@ struct smscore_gpio_config {
#define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1
u8 inputcharacteristics;
-#define SMS_GPIO_OUTPUTSLEWRATE_FAST 0
-#define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1
+#define SMS_GPIO_OUTPUTSLEWRATE_SLOW 0 /* 10xx */
+#define SMS_GPIO_OUTPUTSLEWRATE_FAST 1 /* 10xx */
+
+#define SMS_GPIO_OUTPUTSLEWRATE_0_45_V_NS 0 /* 11xx */
+#define SMS_GPIO_OUTPUTSLEWRATE_0_9_V_NS 1 /* 11xx */
+#define SMS_GPIO_OUTPUTSLEWRATE_1_7_V_NS 2 /* 11xx */
+#define SMS_GPIO_OUTPUTSLEWRATE_3_3_V_NS 3 /* 11xx */
u8 outputslewrate;
-#define SMS_GPIO_OUTPUTDRIVING_4mA 0
-#define SMS_GPIO_OUTPUTDRIVING_8mA 1
-#define SMS_GPIO_OUTPUTDRIVING_12mA 2
-#define SMS_GPIO_OUTPUTDRIVING_16mA 3
+#define SMS_GPIO_OUTPUTDRIVING_S_4mA 0 /* 10xx */
+#define SMS_GPIO_OUTPUTDRIVING_S_8mA 1 /* 10xx */
+#define SMS_GPIO_OUTPUTDRIVING_S_12mA 2 /* 10xx */
+#define SMS_GPIO_OUTPUTDRIVING_S_16mA 3 /* 10xx */
+
+#define SMS_GPIO_OUTPUTDRIVING_1_5mA 0 /* 11xx */
+#define SMS_GPIO_OUTPUTDRIVING_2_8mA 1 /* 11xx */
+#define SMS_GPIO_OUTPUTDRIVING_4mA 2 /* 11xx */
+#define SMS_GPIO_OUTPUTDRIVING_7mA 3 /* 11xx */
+#define SMS_GPIO_OUTPUTDRIVING_10mA 4 /* 11xx */
+#define SMS_GPIO_OUTPUTDRIVING_11mA 5 /* 11xx */
+#define SMS_GPIO_OUTPUTDRIVING_14mA 6 /* 11xx */
+#define SMS_GPIO_OUTPUTDRIVING_16mA 7 /* 11xx */
u8 outputdriving;
};
@@ -581,9 +595,10 @@ 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);
-int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
- struct smscore_gpio_config *pinconfig);
-int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level);
+int smscore_gpio_configure(struct smscore_device_t *coredev, u8 pin,
+ struct smscore_gpio_config *gpioconfig, int wait);
+int smscore_gpio_set_level(struct smscore_device_t *coredev,
+ u8 pin, u8 level, int wait);
void smscore_set_board_id(struct smscore_device_t *core, int id);
int smscore_get_board_id(struct smscore_device_t *core);
--
1.5.6.3
More information about the kernel-team
mailing list