/** * plat-mt6755.c * **/ #include #include #include #include #include #include #include #include #if !defined(CONFIG_MTK_CLKMGR) # include #else # include #endif #include "ff_log.h" # undef LOG_TAG #define LOG_TAG "mt6833" int ff_ctl_enable_power(bool on); int ff_ctl_init_pins(int *irq_num); #ifdef CONFIG_MT6360_LDO static struct regulator *fp_mt6360_ldo = NULL; #endif extern int up_finger_set_reset(int cmd); extern int up_finger_set_irq(int cmd); extern int up_finger_set_spi_mode(int cmd); /* TODO: */ #define FF_COMPATIBLE_NODE_1 "mediatek,up_finger" //#define FF_COMPATIBLE_NODE_2 "mediatek,fpc1145" #define FF_COMPATIBLE_NODE_3 "focaltech,fingerprint-spidev" /* Define pinctrl state types. */ #if 0 typedef enum { FF_PINCTRL_STATE_SPI_CS_ACT, FF_PINCTRL_STATE_SPI_CK_ACT, FF_PINCTRL_STATE_SPI_MOSI_ACT, FF_PINCTRL_STATE_SPI_MISO_ACT, FF_PINCTRL_STATE_PWR_ACT, FF_PINCTRL_STATE_PWR_CLR, FF_PINCTRL_STATE_RST_ACT, FF_PINCTRL_STATE_RST_CLR, FF_PINCTRL_STATE_INT_ACT, FF_PINCTRL_STATE_MAXIMUM /* Array size */ } ff_pinctrl_state_t; /* Define pinctrl state names. */ static const char *g_pinctrl_state_names[FF_PINCTRL_STATE_MAXIMUM] = { "csb_spi", "clk_spi", "mosi_spi", "miso_spi", "power_on", "power_off", "reset_low", "reset_high", "irq_gpio", }; #endif /* Native context and its singleton instance. */ typedef struct { //struct pinctrl *pinctrl; //struct pinctrl_state *pin_states[FF_PINCTRL_STATE_MAXIMUM]; #if !defined(CONFIG_MTK_CLKMGR) struct clk *spiclk; #endif bool b_spiclk_enabled; } ff_mt6833_context_t; static ff_mt6833_context_t ff_mt6833_context, *g_context = &ff_mt6833_context; int ff_ctl_init_pins(int *irq_num) { int err = 0; struct device_node *dev_node = NULL; struct device_node *spi_node = NULL; struct platform_device *pdev = NULL; printk("'%s' zg502 enter.", __func__); /* Find device tree node. */ dev_node = of_find_compatible_node(NULL, NULL, FF_COMPATIBLE_NODE_1); if (!dev_node) { FF_LOGE("of_find_compatible_node(.., '%s') failed.", FF_COMPATIBLE_NODE_1); return (-ENODEV); } *irq_num = irq_of_parse_and_map(dev_node, 0); FF_LOGD("irq number is %d.", *irq_num); #if 0 /* Retrieve the pinctrl handler. */ g_context->pinctrl = devm_pinctrl_get(&pdev->dev); if (!g_context->pinctrl) { FF_LOGE("devm_pinctrl_get(..) failed."); return (-ENODEV); } /* Register all pins. */ for (i = 0; i < FF_PINCTRL_STATE_MAXIMUM; ++i) { g_context->pin_states[i] = pinctrl_lookup_state(g_context->pinctrl, g_pinctrl_state_names[i]); if (!g_context->pin_states[i]) { FF_LOGE("can't find pinctrl state for '%s'.", g_pinctrl_state_names[i]); err = (-ENODEV); break; } } if (i < FF_PINCTRL_STATE_MAXIMUM) { return (-ENODEV); } /* Initialize the SPI pins. */ err = pinctrl_select_state(g_context->pinctrl, g_context->pin_states[FF_PINCTRL_STATE_SPI_CS_ACT]); err = pinctrl_select_state(g_context->pinctrl, g_context->pin_states[FF_PINCTRL_STATE_SPI_CK_ACT]); err = pinctrl_select_state(g_context->pinctrl, g_context->pin_states[FF_PINCTRL_STATE_SPI_MOSI_ACT]); err = pinctrl_select_state(g_context->pinctrl, g_context->pin_states[FF_PINCTRL_STATE_SPI_MISO_ACT]); /* Initialize the INT pin. */ err = pinctrl_select_state(g_context->pinctrl, g_context->pin_states[FF_PINCTRL_STATE_INT_ACT]); #endif up_finger_set_spi_mode(1); up_finger_set_irq(1); #if !defined(CONFIG_MTK_CLKMGR) // // Retrieve the clock source of the SPI controller. // /* 3-1: Find device tree node. */ dev_node = of_find_compatible_node(NULL, NULL, FF_COMPATIBLE_NODE_3); if (!dev_node) { FF_LOGE("of_find_compatible_node(.., '%s') failed.", FF_COMPATIBLE_NODE_3); return (-ENODEV); } spi_node = of_get_parent(dev_node); if (!spi_node) { FF_LOGE("of_find_spi_node failed."); return (-ENODEV); } /* 3-2: Convert to platform device. */ pdev = of_find_device_by_node(spi_node); if (!pdev) { FF_LOGE("of_find_device_by_node(..) failed."); return (-ENODEV); } else { //u32 frequency, div; //err = of_property_read_u32(pdev->dev.of_node, "clock-frequency", &frequency); //err = of_property_read_u32(pdev->dev.of_node, "clock-div", &div); FF_LOGD("spi controller(#%d) name: %s.", pdev->id, pdev->name); //FF_LOGD("spi controller(#%d) clk : %dHz.", pdev->id, frequency / div); } /* 3-3: Retrieve the SPI clk handler. */ g_context->spiclk = devm_clk_get(&pdev->dev, "spi-clk"); if (!g_context->spiclk) { FF_LOGE("devm_clk_get(..) failed."); return (-ENODEV); } #endif FF_LOGV("'%s' leave.", __func__); return err; } int ff_ctl_free_pins(void) { int err = 0; FF_LOGV("'%s' enter.", __func__); // TODO: FF_LOGV("'%s' leave.", __func__); return err; } int ff_ctl_enable_spiclk(bool on) { int err = 0; FF_LOGV("'%s' enter.", __func__); FF_LOGD("clock: '%s'.", on ? "enable" : "disabled"); if (unlikely(!g_context->spiclk)) { return (-ENOSYS); } #if !defined(CONFIG_MTK_CLKMGR) /* Prepare the clock source. */ err = clk_prepare(g_context->spiclk); #endif /* Control the clock source. */ if (on && !g_context->b_spiclk_enabled) { #if !defined(CONFIG_MTK_CLKMGR) err = clk_enable(g_context->spiclk); if (err) { FF_LOGE("clk_enable(..) = %d.", err); } #else enable_clock(MT_CG_PERI_SPI0, "spi"); #endif g_context->b_spiclk_enabled = true; } else if (!on && g_context->b_spiclk_enabled) { #if !defined(CONFIG_MTK_CLKMGR) clk_disable(g_context->spiclk); #else disable_clock(MT_CG_PERI_SPI0, "spi"); #endif g_context->b_spiclk_enabled = false; } FF_LOGV("'%s' leave.", __func__); return err; } #if 1 //extern struct spi_device *g_spidev; int ff_ctl_enable_power(bool on){ int ret = 0; fp_mt6360_ldo = regulator_get(NULL, "VFP"); // ret = mtk_regulator_get(NULL, "irtx_ldo", &fp_mt6360_ldo); // if (ret < 0) { if (IS_ERR(fp_mt6360_ldo)){ ret = PTR_ERR(fp_mt6360_ldo); // return -1; } else{ ret = regulator_set_voltage(fp_mt6360_ldo, 2800000, 2800000); // ret = mtk_regulator_set_voltage(&fp_mt6360_ldo, 2800000, 2800000); if (ret < 0) { return -1; } if (on != 0) { ret = regulator_enable(fp_mt6360_ldo); // ret = mtk_regulator_enable(&fp_mt6360_ldo, true); if (ret < 0) { return -1; } } else { ret = regulator_disable(fp_mt6360_ldo); // ret = mtk_regulator_enable(&fp_mt6360_ldo, true); if (ret < 0) { return -1; } } } // up_finger_set_18v_power(1); return 0; } #endif int ff_ctl_reset_device(void) { int err = 0; FF_LOGV("'%s' enter.", __func__); up_finger_set_reset(0); mdelay(10); up_finger_set_reset(1); #if 0 if (unlikely(!g_context->pinctrl)) { return (-ENOSYS); } /* 3-1: Pull down RST pin. */ err = pinctrl_select_state(g_context->pinctrl, g_context->pin_states[FF_PINCTRL_STATE_RST_ACT]); /* 3-2: Delay for 10ms. */ mdelay(10); /* Pull up RST pin. */ err = pinctrl_select_state(g_context->pinctrl, g_context->pin_states[FF_PINCTRL_STATE_RST_CLR]); #endif FF_LOGV("'%s' leave.", __func__); return err; } const char *ff_ctl_arch_str(void) { return CONFIG_MTK_PLATFORM; }