|
@@ -331,3 +331,195 @@ static const short da850_evm_nor_pins[] = {
|
|
DA850_EMA_A_10, DA850_EMA_A_11, DA850_EMA_A_12, DA850_EMA_A_13,
|
|
DA850_EMA_A_10, DA850_EMA_A_11, DA850_EMA_A_12, DA850_EMA_A_13,
|
|
DA850_EMA_A_14, DA850_EMA_A_15, DA850_EMA_A_16, DA850_EMA_A_17,
|
|
DA850_EMA_A_14, DA850_EMA_A_15, DA850_EMA_A_16, DA850_EMA_A_17,
|
|
DA850_EMA_A_18, DA850_EMA_A_19, DA850_EMA_A_20, DA850_EMA_A_21,
|
|
DA850_EMA_A_18, DA850_EMA_A_19, DA850_EMA_A_20, DA850_EMA_A_21,
|
|
|
|
+ DA850_EMA_A_22, DA850_EMA_A_23,
|
|
|
|
+ -1
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+#if defined(CONFIG_MMC_DAVINCI) || \
|
|
|
|
+ defined(CONFIG_MMC_DAVINCI_MODULE)
|
|
|
|
+#define HAS_MMC 1
|
|
|
|
+#else
|
|
|
|
+#define HAS_MMC 0
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+static inline void da850_evm_setup_nor_nand(void)
|
|
|
|
+{
|
|
|
|
+ int ret = 0;
|
|
|
|
+
|
|
|
|
+ if (!HAS_MMC) {
|
|
|
|
+ ret = davinci_cfg_reg_list(da850_evm_nand_pins);
|
|
|
|
+ if (ret)
|
|
|
|
+ pr_warning("da850_evm_init: nand mux setup failed: "
|
|
|
|
+ "%d\n", ret);
|
|
|
|
+
|
|
|
|
+ ret = davinci_cfg_reg_list(da850_evm_nor_pins);
|
|
|
|
+ if (ret)
|
|
|
|
+ pr_warning("da850_evm_init: nor mux setup failed: %d\n",
|
|
|
|
+ ret);
|
|
|
|
+
|
|
|
|
+ da850_evm_init_nor();
|
|
|
|
+
|
|
|
|
+ platform_add_devices(da850_evm_devices,
|
|
|
|
+ ARRAY_SIZE(da850_evm_devices));
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_DA850_UI_RMII
|
|
|
|
+static inline void da850_evm_setup_emac_rmii(int rmii_sel)
|
|
|
|
+{
|
|
|
|
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
|
|
|
|
+
|
|
|
|
+ soc_info->emac_pdata->rmii_en = 1;
|
|
|
|
+ gpio_set_value_cansleep(rmii_sel, 0);
|
|
|
|
+}
|
|
|
|
+#else
|
|
|
|
+static inline void da850_evm_setup_emac_rmii(int rmii_sel) { }
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+#define DA850_KEYS_DEBOUNCE_MS 10
|
|
|
|
+/*
|
|
|
|
+ * At 200ms polling interval it is possible to miss an
|
|
|
|
+ * event by tapping very lightly on the push button but most
|
|
|
|
+ * pushes do result in an event; longer intervals require the
|
|
|
|
+ * user to hold the button whereas shorter intervals require
|
|
|
|
+ * more CPU time for polling.
|
|
|
|
+ */
|
|
|
|
+#define DA850_GPIO_KEYS_POLL_MS 200
|
|
|
|
+
|
|
|
|
+enum da850_evm_ui_exp_pins {
|
|
|
|
+ DA850_EVM_UI_EXP_SEL_C = 5,
|
|
|
|
+ DA850_EVM_UI_EXP_SEL_B,
|
|
|
|
+ DA850_EVM_UI_EXP_SEL_A,
|
|
|
|
+ DA850_EVM_UI_EXP_PB8,
|
|
|
|
+ DA850_EVM_UI_EXP_PB7,
|
|
|
|
+ DA850_EVM_UI_EXP_PB6,
|
|
|
|
+ DA850_EVM_UI_EXP_PB5,
|
|
|
|
+ DA850_EVM_UI_EXP_PB4,
|
|
|
|
+ DA850_EVM_UI_EXP_PB3,
|
|
|
|
+ DA850_EVM_UI_EXP_PB2,
|
|
|
|
+ DA850_EVM_UI_EXP_PB1,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const char const *da850_evm_ui_exp[] = {
|
|
|
|
+ [DA850_EVM_UI_EXP_SEL_C] = "sel_c",
|
|
|
|
+ [DA850_EVM_UI_EXP_SEL_B] = "sel_b",
|
|
|
|
+ [DA850_EVM_UI_EXP_SEL_A] = "sel_a",
|
|
|
|
+ [DA850_EVM_UI_EXP_PB8] = "pb8",
|
|
|
|
+ [DA850_EVM_UI_EXP_PB7] = "pb7",
|
|
|
|
+ [DA850_EVM_UI_EXP_PB6] = "pb6",
|
|
|
|
+ [DA850_EVM_UI_EXP_PB5] = "pb5",
|
|
|
|
+ [DA850_EVM_UI_EXP_PB4] = "pb4",
|
|
|
|
+ [DA850_EVM_UI_EXP_PB3] = "pb3",
|
|
|
|
+ [DA850_EVM_UI_EXP_PB2] = "pb2",
|
|
|
|
+ [DA850_EVM_UI_EXP_PB1] = "pb1",
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+#define DA850_N_UI_PB 8
|
|
|
|
+
|
|
|
|
+static struct gpio_keys_button da850_evm_ui_keys[] = {
|
|
|
|
+ [0 ... DA850_N_UI_PB - 1] = {
|
|
|
|
+ .type = EV_KEY,
|
|
|
|
+ .active_low = 1,
|
|
|
|
+ .wakeup = 0,
|
|
|
|
+ .debounce_interval = DA850_KEYS_DEBOUNCE_MS,
|
|
|
|
+ .code = -1, /* assigned at runtime */
|
|
|
|
+ .gpio = -1, /* assigned at runtime */
|
|
|
|
+ .desc = NULL, /* assigned at runtime */
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct gpio_keys_platform_data da850_evm_ui_keys_pdata = {
|
|
|
|
+ .buttons = da850_evm_ui_keys,
|
|
|
|
+ .nbuttons = ARRAY_SIZE(da850_evm_ui_keys),
|
|
|
|
+ .poll_interval = DA850_GPIO_KEYS_POLL_MS,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct platform_device da850_evm_ui_keys_device = {
|
|
|
|
+ .name = "gpio-keys-polled",
|
|
|
|
+ .id = 0,
|
|
|
|
+ .dev = {
|
|
|
|
+ .platform_data = &da850_evm_ui_keys_pdata
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static void da850_evm_ui_keys_init(unsigned gpio)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+ struct gpio_keys_button *button;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < DA850_N_UI_PB; i++) {
|
|
|
|
+ button = &da850_evm_ui_keys[i];
|
|
|
|
+ button->code = KEY_F8 - i;
|
|
|
|
+ button->desc = (char *)
|
|
|
|
+ da850_evm_ui_exp[DA850_EVM_UI_EXP_PB8 + i];
|
|
|
|
+ button->gpio = gpio + DA850_EVM_UI_EXP_PB8 + i;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_DA850_UI_SD_VIDEO_PORT
|
|
|
|
+static inline void da850_evm_setup_video_port(int video_sel)
|
|
|
|
+{
|
|
|
|
+ gpio_set_value_cansleep(video_sel, 0);
|
|
|
|
+}
|
|
|
|
+#else
|
|
|
|
+static inline void da850_evm_setup_video_port(int video_sel) { }
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
|
|
|
|
+ unsigned ngpio, void *c)
|
|
|
|
+{
|
|
|
|
+ int sel_a, sel_b, sel_c, ret;
|
|
|
|
+
|
|
|
|
+ sel_a = gpio + DA850_EVM_UI_EXP_SEL_A;
|
|
|
|
+ sel_b = gpio + DA850_EVM_UI_EXP_SEL_B;
|
|
|
|
+ sel_c = gpio + DA850_EVM_UI_EXP_SEL_C;
|
|
|
|
+
|
|
|
|
+ ret = gpio_request(sel_a, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_A]);
|
|
|
|
+ if (ret) {
|
|
|
|
+ pr_warning("Cannot open UI expander pin %d\n", sel_a);
|
|
|
|
+ goto exp_setup_sela_fail;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = gpio_request(sel_b, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_B]);
|
|
|
|
+ if (ret) {
|
|
|
|
+ pr_warning("Cannot open UI expander pin %d\n", sel_b);
|
|
|
|
+ goto exp_setup_selb_fail;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = gpio_request(sel_c, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_C]);
|
|
|
|
+ if (ret) {
|
|
|
|
+ pr_warning("Cannot open UI expander pin %d\n", sel_c);
|
|
|
|
+ goto exp_setup_selc_fail;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* deselect all functionalities */
|
|
|
|
+ gpio_direction_output(sel_a, 1);
|
|
|
|
+ gpio_direction_output(sel_b, 1);
|
|
|
|
+ gpio_direction_output(sel_c, 1);
|
|
|
|
+
|
|
|
|
+ da850_evm_ui_keys_init(gpio);
|
|
|
|
+ ret = platform_device_register(&da850_evm_ui_keys_device);
|
|
|
|
+ if (ret) {
|
|
|
|
+ pr_warning("Could not register UI GPIO expander push-buttons");
|
|
|
|
+ goto exp_setup_keys_fail;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pr_info("DA850/OMAP-L138 EVM UI card detected\n");
|
|
|
|
+
|
|
|
|
+ da850_evm_setup_nor_nand();
|
|
|
|
+
|
|
|
|
+ da850_evm_setup_emac_rmii(sel_a);
|
|
|
|
+
|
|
|
|
+ da850_evm_setup_video_port(sel_c);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+exp_setup_keys_fail:
|
|
|
|
+ gpio_free(sel_c);
|
|
|
|
+exp_setup_selc_fail:
|
|
|
|
+ gpio_free(sel_b);
|
|
|
|
+exp_setup_selb_fail:
|
|
|
|
+ gpio_free(sel_a);
|
|
|
|
+exp_setup_sela_fail:
|
|
|
|
+ return ret;
|