kernel-brax3-ubuntu-touch/drivers/input/fingerprint/microarray_v4_0_0_1/mtk-settings.c
erascape f319b992b1 kernel-5.15: Initial import brax3 UT kernel
* halium configs enabled

Signed-off-by: erascape <erascape@proton.me>
2025-09-23 15:17:10 +00:00

496 lines
14 KiB
C
Executable file

/* Copyright (C) MicroArray
* MicroArray Fprint Driver Code
* mtk-settings.c
* Date: 2017-3-15
* Version: v4.0.06
* Author: guq
* Contact: guq@microarray.com.cn
*/
#include "mtk-settings.h"
#ifdef TEE_ID_COMPATIBLE_TRUSTKERNEL
#include <linux/tee_fp.h>
#endif
static int ret;
//pin control sturct data, define using for the dts settings,
struct pinctrl *mas_finger_pinctrl;
struct pinctrl_state //*mas_finger_power2v8_on, *mas_finger_power2v8_off, //power2v8
//*mas_finger_power1v8_on, *mas_finger_power1v8_off, //power1v8
*mas_finger_rst_on, *mas_finger_rst_off, //rst
*mas_finger_eint_on, *mas_finger_eint_off, //eint
*mas_spi_ck_on, //for ck
*mas_spi_cs_on, //for cs
*mas_spi_mi_on, *mas_spi_mi_off, //for mi
*mas_spi_mo_on, *mas_spi_mo_off, //for mo
*mas_spi_default; //same odms only use default to setting the dts
static struct device_node *node;
static unsigned int finger_int_pin;
/**
* the platform struct start,for getting the platform device to set gpio state
*/
//#ifdef CONFIG_OF
static struct of_device_id sof_match[] = {
{ .compatible = MA_DTS_NAME, },
{},
};
static struct of_device_id sof_dev_match[] = {
{ .compatible = "prize,mas_fingerprint", },
{},
};
MODULE_DEVICE_TABLE(of, sof_match);
MODULE_DEVICE_TABLE(of, sof_dev_match);
//#endif
static struct platform_driver spdrv = {
.probe = mas_plat_probe,
.remove = mas_plat_remove,
.driver = {
.name = MA_DRV_NAME,
.owner = THIS_MODULE,
#ifdef CONFIG_OF
.of_match_table = sof_match,
//.of_match_table = of_match_ptr(sof_match),
#endif
}
};
/**
* the platform struct start,for getting the platform device to set gpio state end
*/
/**
* the spi struct date start,for getting the spi_device to set the spi clock enable start
*/
struct spi_device_id sdev_id = {MA_DRV_NAME, 0};
struct spi_driver sdrv = {
.driver = {
.name = MA_DRV_NAME,
.bus = &spi_bus_type,
.owner = THIS_MODULE,
#ifdef CONFIG_OF
.of_match_table = sof_dev_match,
#endif
},
.probe = mas_probe,
.remove = mas_remove,
// .id_table = &sdev_id,
};
//driver end
#ifndef CONFIG_OF
static struct mt_chip_conf smt_conf = {
.setuptime=15,
.holdtime=15,
.high_time=15, // 10--6m 15--4m 20--3m 30--2m [ 60--1m 120--0.5m 300--0.2m]
.low_time=15,
.cs_idletime=15,
.ulthgh_thrsh=0,
.cpol=0,
.cpha=0,
.rx_mlsb=SPI_MSB,
.tx_mlsb=SPI_MSB,
.tx_endian=0,
.rx_endian=0,
.com_mod=FIFO_TRANSFER,
.pause=0,
.finish_intr=5,
.deassert=0,
.ulthigh=0,
.tckdly=0,
};
struct spi_board_info smt_info[] __initdata = {
[0] = {
.modalias = MA_DRV_NAME,
.max_speed_hz = (4*1000000),
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_0,
.controller_data = &smt_conf,
},
};
//device end
void mas_set_spi_controller_data(struct spi_device *spi)
{
spi->mode = SPI_MODE_0;
spi->bits_per_word = 8;
spi->max_speed_hz = SPI_SPEED;
spi->controller_data = (void *)&smt_conf ;
spi_setup(spi);
}
/**
* the spi struct date start,for getting the spi_device to set the spi clock enable end
*/
void mas_select_transfer(struct spi_device *spi, int len) {
static int mode = -1;
int tmp = len>32? DMA_TRANSFER: FIFO_TRANSFER;
struct mt_chip_conf *conf = &smt_conf;
if(tmp!=mode) {
conf = (struct mt_chip_conf *) spi->controller_data;
conf->com_mod = tmp;
spi_setup(spi);
mode = tmp;
}
}
/*
* set spi speed, often we must check whether the setting is efficient
*/
void ma_spi_change(struct spi_device *spi, unsigned int speed, int flag)
{
struct mt_chip_conf *mcc = (struct mt_chip_conf *)spi->controller_data;
if(flag == 0) {
mcc->com_mod = FIFO_TRANSFER;
} else {
mcc->com_mod = DMA_TRANSFER;
}
mcc->high_time = speed;
mcc->low_time = speed;
if(spi_setup(spi) < 0){
MALOGE("change the spi error!\n");
}
}
#endif
int mas_do_some_for_probe(struct spi_device *spi){
return 0;
}
int __init mas_get_platform(void) {
MALOGD("start!");
ret = platform_driver_register(&spdrv);
if(ret){
printk("===wys===mas_get_platform= driver_register==error=\n");
return ret;
}
/*MALOGD("start board info");
ret = spi_register_board_info(smt_info, ARRAY_SIZE(smt_info));
if(ret){
MALOGE("spi_register_board_info");
}*/
MALOGD("start register spi");
ret = spi_register_driver(&sdrv);
if(ret) {
printk("==wys==spi_register_driver===error===\n");
return ret;
}
return ret;
}
int mas_remove_platform(void){
spi_unregister_driver(&sdrv);
platform_driver_unregister(&spdrv);
return 0;
}
int mas_finger_get_gpio_info(struct platform_device *pdev){
MALOGD("start!");
node = of_find_compatible_node(NULL, NULL, MA_DTS_NAME);
//pdev = of_find_device_by_node(node);
mas_finger_pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(mas_finger_pinctrl)) {
ret = PTR_ERR(mas_finger_pinctrl);
dev_err(&pdev->dev, "mas_finger_pinctrl cannot find pinctrl\n");
return ret;
}
mas_spi_mi_on = pinctrl_lookup_state(mas_finger_pinctrl, "fpc_mode_as_mi");
if (IS_ERR(mas_spi_mi_on)) {
ret = PTR_ERR(mas_spi_mi_on);
dev_err(&pdev->dev, " Cannot find mas_spi_mi_on pinctrl!\n");
return ret;
}
mas_spi_mi_off = pinctrl_lookup_state(mas_finger_pinctrl, "fpc_miso_pull_down");
if (IS_ERR(mas_spi_mi_off)) {
ret = PTR_ERR(mas_spi_mi_off);
dev_err(&pdev->dev, " Cannot find mas_spi_mi_off pinctrl!\n");
return ret;
}
mas_spi_mo_on = pinctrl_lookup_state(mas_finger_pinctrl, "fpc_mode_as_mo");
if (IS_ERR(mas_spi_mo_on)) {
ret = PTR_ERR(mas_spi_mo_on);
dev_err(&pdev->dev, " Cannot find mas_spi_mo_on pinctrl!\n");
return ret;
}
mas_spi_mo_off = pinctrl_lookup_state(mas_finger_pinctrl, "fpc_mosi_pull_down");
if (IS_ERR(mas_spi_mo_off)) {
ret = PTR_ERR(mas_spi_mo_off);
dev_err(&pdev->dev, " Cannot find mas_spi_mo_off!\n");
return ret;
}
mas_spi_ck_on = pinctrl_lookup_state(mas_finger_pinctrl, "fpc_mode_as_ck");
if (IS_ERR(mas_spi_ck_on)) {
ret = PTR_ERR(mas_spi_ck_on);
dev_err(&pdev->dev, " Cannot find mas_spi_ck_on pinctrl!\n");
return ret;
}
// mas_spi_ck_off = pinctrl_lookup_state(mas_finger_pinctrl, "fpc_pins_clk_as_gpio");
// if (IS_ERR(mas_spi_ck_off)) {
// ret = PTR_ERR(mas_spi_ck_off);
// dev_err(&pdev->dev, " Cannot find mas_spi_ck_off pinctrl !\n");
// return ret;
// }
mas_spi_cs_on = pinctrl_lookup_state(mas_finger_pinctrl, "fpc_mode_as_cs");
if (IS_ERR(mas_spi_cs_on)) {
ret = PTR_ERR(mas_spi_cs_on);
dev_err(&pdev->dev, " Cannot find mas_spi_cs_on pinctrl!\n");
return ret;
}
// mas_spi_cs_off = pinctrl_lookup_state(mas_finger_pinctrl, "fpc_pins_cs_low");
// if (IS_ERR(mas_spi_cs_off)) {
// ret = PTR_ERR(mas_spi_cs_off);
// dev_err(&pdev->dev, " Cannot find mas_spi_cs_off pinctrl!\n");
// return ret;
// }
mas_finger_rst_on = pinctrl_lookup_state(mas_finger_pinctrl, "fpc_pins_rst_high");
if (IS_ERR(mas_finger_rst_on)) {
ret = PTR_ERR(mas_finger_rst_on);
dev_err(&pdev->dev, " Cannot find mas_finger_rst_on pinctrl!\n");
return ret;
}
mas_finger_rst_off = pinctrl_lookup_state(mas_finger_pinctrl, "fpc_pins_rst_low");
if (IS_ERR(mas_finger_rst_off)) {
ret = PTR_ERR(mas_finger_rst_off);
dev_err(&pdev->dev, " Cannot find mas_finger_rst_off pinctrl!\n");
return ret;
}
mas_finger_eint_on = pinctrl_lookup_state(mas_finger_pinctrl, "fpc_eint_as_int");
if (IS_ERR(mas_finger_eint_on)) {
ret = PTR_ERR(mas_finger_eint_on);
dev_err(&pdev->dev, " Cannot find mas_finger_eint_on pinctrl!\n");
return ret;
}
MALOGD("end!");
return 0;
}
void mas_free_dts_info(void)
{
if(mas_finger_pinctrl != NULL) devm_pinctrl_put(mas_finger_pinctrl);
}
int mas_finger_set_spi(int cmd){
//#if 0
switch(cmd)
{
case 0:
// if( (!IS_ERR(mas_spi_cs_off)) && (!IS_ERR(mas_spi_ck_off)) && (!IS_ERR(mas_spi_mi_off)) && (!IS_ERR(mas_spi_mo_off)) ){
if( (!IS_ERR(mas_spi_mi_off)) && (!IS_ERR(mas_spi_mo_off)) ){
// pinctrl_select_state(mas_finger_pinctrl, mas_spi_cs_off);
// pinctrl_select_state(mas_finger_pinctrl, mas_spi_ck_off);
pinctrl_select_state(mas_finger_pinctrl, mas_spi_mi_off);
pinctrl_select_state(mas_finger_pinctrl, mas_spi_mo_off);
MALOGE("mas_spi_gpio_slect_pinctrl cmd=0 ok!");
}else{
MALOGE("mas_spi_gpio_slect_pinctrl cmd=0 err!");
return -1;
}
break;
case 1:
if( (!IS_ERR(mas_spi_cs_on)) && (!IS_ERR(mas_spi_ck_on)) && (!IS_ERR(mas_spi_mi_on)) && (!IS_ERR(mas_spi_mo_on)) ){
pinctrl_select_state(mas_finger_pinctrl, mas_spi_cs_on);
pinctrl_select_state(mas_finger_pinctrl, mas_spi_ck_on);
pinctrl_select_state(mas_finger_pinctrl, mas_spi_mi_on);
pinctrl_select_state(mas_finger_pinctrl, mas_spi_mo_on);
MALOGE("mas_spi_gpio_slect_pinctrl cmd=1 ok!");
}else{
MALOGE("mas_spi_gpio_slect_pinctrl cmd=1 err!");
return -1;
}
break;
}
//#endif
return 0;
}
void mas_finger_set_reset(int enable)
{
if(enable){
printk("microarray pri ,reset set 1 \n");
pinctrl_select_state(mas_finger_pinctrl, mas_finger_rst_on);
msleep(10);
pinctrl_select_state(mas_finger_pinctrl, mas_finger_rst_off);
msleep(20);
pinctrl_select_state(mas_finger_pinctrl, mas_finger_rst_on);
}else{
printk("microarray pri ,reset set 0 \n");
pinctrl_select_state(mas_finger_pinctrl, mas_finger_rst_off);
}
}
void mas_finger_reset(int enable)
{
if(enable){
pinctrl_select_state(mas_finger_pinctrl, mas_finger_rst_on);
msleep(10);
pinctrl_select_state(mas_finger_pinctrl, mas_finger_rst_off);
msleep(20);
pinctrl_select_state(mas_finger_pinctrl, mas_finger_rst_on);
}else{
pinctrl_select_state(mas_finger_pinctrl, mas_finger_rst_off);
}
}
int mas_finger_set_power(int cmd)
{
int ret = 0;
if(cmd){
printk("microarray pri ,power set 1 \n");
#if defined(CONFIG_PRIZE_FP_USE_VFP)
ret = vfp_regulator_ctl(1);
#endif
mas_finger_set_reset(1);
}else{
printk("microarray pri ,power set 0 \n");
#if defined(CONFIG_PRIZE_FP_USE_VFP)
ret = vfp_regulator_ctl(0);
#endif
mas_finger_set_reset(0);
}
return ret;
}
/*
* this is a demo function,if the power on-off switch by other way
* modify it as the right way
* on_off 1 on 0 off
*/
int mas_switch_power(unsigned int on_off){
mas_finger_set_power(on_off); //use this fuction directly if the dts way
return 0;
}
int mas_finger_set_eint(int cmd)
{
switch (cmd)
{
case 0 :
if(!IS_ERR(mas_finger_eint_off)){
pinctrl_select_state(mas_finger_pinctrl, mas_finger_eint_off);
}else{
MALOGE("mas_eint_gpio_slect_pinctrl cmd=0 err!");
return -1;
}
break;
case 1 :
if(!IS_ERR(mas_finger_eint_on)){
pinctrl_select_state(mas_finger_pinctrl, mas_finger_eint_on);
}else{
MALOGE("mas_eint_gpio_slect_pinctrl cmd=1 err!");
return -1;
}
break;
}
return 0;
}
int mas_finger_set_gpio_info(int cmd){
ret = 0;
MALOGD("start!");
ret |= mas_finger_set_spi(cmd);
ret |= mas_finger_set_power(cmd);
// ret |= mas_finger_set_eint(cmd);
MALOGD("end!");
return ret;
}
void mas_enable_spi_clock(struct spi_device *spi){
#if defined(TEE_ID_COMPATIBLE_TRUSTKERNEL) || defined(TEE_ID_COMPATIBLE_MICROTRUST)
#ifdef CONFIG_MTK_CLKMGR
enable_clock(MT_CG_PERI_SPI0, "spi");
#elif defined(MT6797)
mt_spi_enable_clk(spi_master_get_devdata(spi->master));
#else
mt_spi_enable_master_clk(spi);
//enable_clk();
#endif
#endif
}
void mas_disable_spi_clock(struct spi_device *spi){
#if defined(TEE_ID_COMPATIBLE_TRUSTKERNEL) || defined(TEE_ID_COMPATIBLE_MICROTRUST)
#ifdef CONFIG_MTK_CLKMGR
disable_clock(MT_CG_PERI_SPI0, "spi");
#elif defined(MT6797)
mt_spi_disable_clk(spi_master_get_devdata(spi->master));
#else
mt_spi_disable_master_clk(spi);
//disable_clk();
#endif
#endif
}
int mas_tee_spi_transfer(u8 *txb, u8 *rxb, int len) {
int val;
val = 0;
#ifdef TEE_ID_COMPATIBLE_TRUSTKERNEL
val = tee_spi_transfer(&smt_conf,sizeof(struct mt_chip_conf),txb, rxb, 4);
#endif
return val;
}
unsigned int mas_get_irq(struct device *dev){
int irq_num;
finger_int_pin = of_get_named_gpio_flags(dev->of_node,
"fingerprint,touch-int-gpio", 0, NULL);
if (!gpio_is_valid(finger_int_pin)){
MALOGE("invalid irq gpio!");
return -EINVAL;
}
gpio_direction_input(finger_int_pin);
irq_num = gpio_to_irq(finger_int_pin);
return irq_num;
}
/*
* this function used for check the interrupt gpio state
* @index 0 gpio level 1 gpio mode, often use 0
* @return 0 gpio low 1 gpio high if index = 1,the return is the gpio mode
* under 0 the of_property_read_u32_index return errno,check the dts as below:
* last but not least use this function must checkt the label on dts file, after is an example:
* ma_finger: ma_finger{
* compatible = "mediatek,afs120x";
* finger_int_pin = <100 0>;
* }
*/
int mas_get_interrupt_gpio(unsigned int index){
int val;
val = __gpio_get_value(finger_int_pin);
//printk if need
return val;
}