kernel/prism: initial support for GFLT300
Color FiberJack (cFJ) is the new FiberJack being developed for the
Go-Long project. It is based on the GFLT110 SoC (Marvell 88F6601).
Change-Id: Id3ca9ec996ad377f5ba1857b79e3959ff8f647f4
diff --git a/arch/arm/configs/gflt110_defconfig b/arch/arm/configs/gflt110_defconfig
index cef0917..25bc9ca 100644
--- a/arch/arm/configs/gflt110_defconfig
+++ b/arch/arm/configs/gflt110_defconfig
@@ -1136,7 +1136,7 @@
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_GPIOLIB=y
# CONFIG_DEBUG_GPIO is not set
-# CONFIG_GPIO_SYSFS is not set
+CONFIG_GPIO_SYSFS=y
#
# Memory mapped GPIO expanders:
diff --git a/arch/arm/mach-feroceon-kw2/Makefile b/arch/arm/mach-feroceon-kw2/Makefile
index bf5e8a9..3fecf47 100755
--- a/arch/arm/mach-feroceon-kw2/Makefile
+++ b/arch/arm/mach-feroceon-kw2/Makefile
@@ -243,6 +243,6 @@
feroceon-$(CONFIG_THERMAL_SENSOR_KW2) += hwmon.o
# Board
+obj-y += fiberjack.o
obj-$(CONFIG_MACH_GFLT200) += board-gflt200.o
obj-$(CONFIG_MACH_GFLT110) += board-gflt110.o
-
diff --git a/arch/arm/mach-feroceon-kw2/board-gflt110.c b/arch/arm/mach-feroceon-kw2/board-gflt110.c
index 5341efb..6d701dc 100644
--- a/arch/arm/mach-feroceon-kw2/board-gflt110.c
+++ b/arch/arm/mach-feroceon-kw2/board-gflt110.c
@@ -1,4 +1,5 @@
#include <boardEnv/mvBoardEnvLib.h>
+#include <fiberjack.h>
#include <gpp/mvGpp.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -10,7 +11,7 @@
#include <linux/platform_device.h>
#include <linux/sysfs.h>
-#define BOARD_NAME "gflt110"
+#define GPIO_PON_PWR_EN 37
struct gflt_led_data {
unsigned gpio;
@@ -18,6 +19,56 @@
struct led_classdev cdev;
};
+struct board_gpio {
+ unsigned gpio;
+ const char *label;
+};
+
+static struct board_gpio board_gpios[] = {
+ {
+ .gpio = GPIO_PON_PWR_EN,
+ .label = "power-enable",
+ },
+};
+
+static int board_gpio_export(struct board_gpio *gpio, struct device *dev)
+{
+ int rc;
+
+ rc = gpio_request(gpio->gpio, gpio->label);
+ if (rc) {
+ pr_err("%s: error %d requesting gpio %u (%s)\n",
+ get_model_name(), rc, gpio->gpio, gpio->label);
+ goto exit;
+ }
+
+ /* this is needed to set gpiolib's out flag for the gpio */
+ rc = gpio_direction_output(gpio->gpio, gpio_get_value(gpio->gpio));
+ if (rc) {
+ pr_err("%s: error %d setting gpio %u (%s) direction\n",
+ get_model_name(), rc, gpio->gpio, gpio->label);
+ goto exit;
+ }
+
+ rc = gpio_export(gpio->gpio, false);
+ if (rc) {
+ pr_err("%s: error %d exporting gpio %u (%s)\n",
+ get_model_name(), rc, gpio->gpio, gpio->label);
+ goto exit;
+ }
+
+ rc = gpio_export_link(dev, gpio->label, gpio->gpio);
+ if (rc) {
+ pr_err("%s: error %d linking gpio %u (%s)\n",
+ get_model_name(), rc, gpio->gpio, gpio->label);
+ goto exit;
+ }
+
+ rc = 0;
+exit:
+ return rc;
+}
+
static ssize_t board_hw_ver_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -110,33 +161,47 @@
int __init board_init(void)
{
+ int i;
int rc;
struct platform_device *pdev;
+ printk("Detected board type: %s\n", get_model_name());
+
/* /sys/devices/platform/<board_name> */
- pdev = platform_device_register_simple(BOARD_NAME, -1, NULL, 0);
+ pdev = platform_device_register_simple(get_model_name(), -1, NULL, 0);
if (IS_ERR(pdev)) {
rc = PTR_ERR(pdev);
- pr_err(BOARD_NAME ": error %d registering device\n", rc);
+ pr_err("%s: error %d registering device\n",
+ get_model_name(), rc);
return rc;
}
/* /sys/devices/platform/board -> /sys/devices/platform/<board_name> */
rc = sysfs_create_link(&pdev->dev.parent->kobj, &pdev->dev.kobj,
- "board");
- if (rc)
- pr_err(BOARD_NAME ": error %d creating link 'board'\n", rc);
+ "board");
+ if (rc) {
+ pr_err("%s: error %d creating link 'board'\n",
+ get_model_name(), rc);
+ }
/* /sys/devices/platform/board/hw_ver */
rc = device_create_file(&pdev->dev, &dev_attr_hw_ver);
- if (rc)
- pr_err(BOARD_NAME ": error %d creating attribute 'hw_ver'\n",
- rc);
+ if (rc) {
+ pr_err("%s: error %d creating attribute 'hw_ver'\n",
+ get_model_name(), rc);
+ }
+
+ if (is_gflt300() == 1) {
+ /* /sys/devices/platform/board/<gpio_name> */
+ for (i = 0; i < ARRAY_SIZE(board_gpios); i++)
+ board_gpio_export(&board_gpios[i], &pdev->dev);
+ }
rc = register_gfltleds(pdev, board_gpio_leds, ARRAY_SIZE(board_gpio_leds));
- if (rc)
- pr_err(BOARD_NAME ": error %d registering GFLT LED device\n",
- rc);
+ if (rc) {
+ pr_err("%s: error %d registering GFLT LED device\n",
+ get_model_name(), rc);
+ }
return 0;
}
diff --git a/arch/arm/mach-feroceon-kw2/fiberjack.c b/arch/arm/mach-feroceon-kw2/fiberjack.c
new file mode 100644
index 0000000..21d4823
--- /dev/null
+++ b/arch/arm/mach-feroceon-kw2/fiberjack.c
@@ -0,0 +1,23 @@
+#include <linux/init.h>
+#include <linux/string.h>
+#include "fiberjack.h"
+
+const char* get_model_name(void) {
+ if (strstr(boot_command_line, "model=gflt300") != NULL)
+ return "gflt300";
+ else if (strstr(boot_command_line, "model=gflt110") != NULL)
+ return "gflt110";
+ else
+ /* If we can't find a match, assume the default which is GFLT110 */
+ return "gflt110";
+}
+
+int parse_model_from_cmdline(const char* model) {
+ if (strstr(boot_command_line, model) != NULL)
+ return 1;
+ return 0;
+}
+
+int is_gflt300(void) {
+ return parse_model_from_cmdline("gflt300");
+}
diff --git a/arch/arm/mach-feroceon-kw2/fiberjack.h b/arch/arm/mach-feroceon-kw2/fiberjack.h
new file mode 100644
index 0000000..ccf89f3
--- /dev/null
+++ b/arch/arm/mach-feroceon-kw2/fiberjack.h
@@ -0,0 +1,6 @@
+#ifndef _FEROCEON_FIBERJACK_H_
+#define _FEROCEON_FIBERJACK_H_
+int is_gflt300(void);
+int parse_model_from_cmdline(char const* model);
+const char* get_model_name(void);
+#endif /* _FEROCEON_FIBERJACK_H_ */
diff --git a/arch/arm/mach-feroceon-kw2/kw2_family/boardEnv/mvBoardEnvSpec.c b/arch/arm/mach-feroceon-kw2/kw2_family/boardEnv/mvBoardEnvSpec.c
index dbcdded..dc7e9e3 100755
--- a/arch/arm/mach-feroceon-kw2/kw2_family/boardEnv/mvBoardEnvSpec.c
+++ b/arch/arm/mach-feroceon-kw2/kw2_family/boardEnv/mvBoardEnvSpec.c
@@ -61,6 +61,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
+#include "fiberjack.h"
#include "mvCommon.h"
#include "mvBoardEnvLib.h"
#include "mvBoardEnvSpec.h"
@@ -1501,6 +1502,18 @@
{BOARD_GPP_PON_XVR_TX_IND, 24},
};
+/* TODO(cgibson): For GFLT200, these are set to:
+ {BOARD_GPP_PON_XVR_TX, 21, 1},
+ {BOARD_GPP_PON_XVR_TX_POWER, 37, 0},
+ Which is correct?
+*/
+MV_BOARD_GPP_INFO gflt300InfoBoardGppInfo[] = {
+ /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
+ {BOARD_GPP_PON_XVR_TX, 17},
+ {BOARD_GPP_PON_XVR_TX_POWER, 11},
+ {BOARD_GPP_PON_XVR_TX_IND, 24},
+};
+
MV_DEV_CS_INFO gflt110InfoBoardDeCsInfo[] = {
/*{deviceCS, params, devType, devWidth} */
#ifdef MV_SPI
@@ -1522,25 +1535,44 @@
}
};
-/*
-MV_BOARD_SPEC_INIT gflt110BoardSpecInit[] = {
- {
- .reg = PMU_POWER_IF_POLARITY_REG,
- .mask = (BIT1),
- .val = 0
- },
- {
- .reg = TBL_TERM,
- .val = TBL_TERM
- }
+MV_BOARD_MPP_INFO gflt300InfoBoardMppConfigValue[] = {
+ {{
+ GFLT300_MPP0_7,
+ GFLT300_MPP8_15,
+ GFLT300_MPP16_23,
+ GFLT300_MPP24_31,
+ GFLT300_MPP32_37
+ }
+ }
};
-*/
+
+static MV_VOID gfltBoardInit(MV_BOARD_INFO *pBoardInfo)
+{
+ if (is_gflt300() == 1) {
+ pBoardInfo->numBoardGppInfo = MV_ARRAY_SIZE(
+ gflt300InfoBoardGppInfo);
+ pBoardInfo->pBoardGppInfo = gflt300InfoBoardGppInfo;
+ pBoardInfo->numBoardMppConfigValue = MV_ARRAY_SIZE(
+ gflt300InfoBoardMppConfigValue);
+ pBoardInfo->pBoardMppConfigValue =
+ gflt300InfoBoardMppConfigValue;
+ pBoardInfo->gppOutEnValLow = GFLT300_GPP_OUT_ENA_LOW;
+ } else {
+ pBoardInfo->numBoardGppInfo = MV_ARRAY_SIZE(
+ gflt110InfoBoardGppInfo);
+ pBoardInfo->pBoardGppInfo = gflt110InfoBoardGppInfo;
+ pBoardInfo->numBoardMppConfigValue = MV_ARRAY_SIZE(
+ gflt110InfoBoardMppConfigValue);
+ pBoardInfo->pBoardMppConfigValue =
+ gflt110InfoBoardMppConfigValue;
+ pBoardInfo->gppOutEnValLow = GFLT110_GPP_OUT_ENA_LOW;
+ }
+}
+
MV_BOARD_INFO gflt110Info = {
.boardName = "GFLT110",
- .numBoardMppTypeValue = MV_ARRAY_SIZE(gflt110InfoBoardMppTypeInfo),
+ .pBoardInit = gfltBoardInit,
.pBoardMppTypeValue = gflt110InfoBoardMppTypeInfo,
- .numBoardMppConfigValue = MV_ARRAY_SIZE(gflt110InfoBoardMppConfigValue),
- .pBoardMppConfigValue = gflt110InfoBoardMppConfigValue,
.intsGppMaskLow = 0,
.intsGppMaskMid = 0,
.intsGppMaskHigh = 0,
@@ -1550,14 +1582,11 @@
.pBoardTwsiDev = gflt110InfoBoardTwsiDev,
.numBoardMacInfo = MV_ARRAY_SIZE(gflt110InfoBoardMacInfo),
.pBoardMacInfo = gflt110InfoBoardMacInfo,
- .numBoardGppInfo = MV_ARRAY_SIZE(gflt110InfoBoardGppInfo),
- .pBoardGppInfo = gflt110InfoBoardGppInfo,
.activeLedsNumber = 0,
.pLedGppPin = NULL,
.ledsPolarity = 0,
/* GPP values */
- .gppOutEnValLow = GFLT110_GPP_OUT_ENA_LOW,
.gppOutEnValMid = GFLT110_GPP_OUT_ENA_MID,
.gppOutEnValHigh = 0,
.gppOutValLow = GFLT110_GPP_OUT_VAL_LOW,
diff --git a/arch/arm/mach-feroceon-kw2/kw2_family/boardEnv/mvBoardEnvSpec.h b/arch/arm/mach-feroceon-kw2/kw2_family/boardEnv/mvBoardEnvSpec.h
index 63e910b..64a804b 100755
--- a/arch/arm/mach-feroceon-kw2/kw2_family/boardEnv/mvBoardEnvSpec.h
+++ b/arch/arm/mach-feroceon-kw2/kw2_family/boardEnv/mvBoardEnvSpec.h
@@ -538,14 +538,21 @@
#define GFLT200_EVT2_GPP_POL_MID 0x0
/***************************************************************************
-** GFLT110
+** GFLT110 & GFLT300
****************************************************************************/
-#define GFLT110_MPP0_7 0x22222220
-#define GFLT110_MPP8_15 0x00000002
+#define GFLT110_MPP0_7 0x22222220
+#define GFLT110_MPP8_15 0x00000002
#define GFLT110_MPP16_23 0x00400000
#define GFLT110_MPP24_31 0x00200550
#define GFLT110_MPP32_37 0x00000000
+/* GFLT300 */
+#define GFLT300_MPP0_7 0x22222220
+#define GFLT300_MPP8_15 0x00000002
+#define GFLT300_MPP16_23 0x00000000
+#define GFLT300_MPP24_31 0x40200504
+#define GFLT300_MPP32_37 0x00000004
+
/* GPPs
1 SPI0_MOSI (out)
2 SPI0_SCK (out)
@@ -566,17 +573,21 @@
37 TX_PD
*/
-#define GFLT110_GPP_OUT_ENA_LOW (BIT0 | BIT14 | BIT16 | BIT17 | BIT18 | BIT19 | BIT22 | BIT23 | BIT24 | BIT27| BIT30 | BIT31)
-#define GFLT110_GPP_OUT_ENA_MID (BIT0 | BIT3 | BIT4)
+#define GFLT110_GPP_OUT_ENA_LOW (BIT0 | BIT14 | BIT16 | BIT17 | BIT18 | BIT19 | BIT22 | BIT23 | BIT24 | BIT27| BIT30 | BIT31)
+
+#define GFLT110_GPP_OUT_ENA_MID (BIT0 | BIT3 | BIT4)
// BIT12 turns the LED blue.
// BIT13 turns the LED red.
-#define GFLT110_GPP_OUT_VAL_LOW BIT13
-#define GFLT110_GPP_OUT_VAL_MID 0x0
+#define GFLT110_GPP_OUT_VAL_LOW BIT13
+#define GFLT110_GPP_OUT_VAL_MID 0x0
#define GFLT110_GPP_POL_LOW (BIT23)
#define GFLT110_GPP_POL_MID 0x0
+/* GFLT300 */
+#define GFLT300_GPP_OUT_ENA_LOW (BIT0 | BIT14 | BIT16 | BIT17 | BIT19 | BIT22 | BIT23 | BIT24 | BIT27| BIT30 | BIT31)
+
/***************************************************************************
** RD-88F6601MC2L
****************************************************************************/