[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