297 lines
7.5 KiB
C
Executable File
297 lines
7.5 KiB
C
Executable File
/**
|
|
* plat-mt6755.c
|
|
*
|
|
**/
|
|
|
|
#include <linux/stddef.h>
|
|
#include <linux/bug.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/pinctrl/consumer.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_irq.h>
|
|
#include <linux/of_platform.h>
|
|
#include <linux/regulator/consumer.h>
|
|
#if !defined(CONFIG_MTK_CLKMGR)
|
|
# include <linux/clk.h>
|
|
#else
|
|
# include <mach/mt_clkmgr.h>
|
|
#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;
|
|
}
|
|
|