fm23驱动程序

一,回声消除的作用
消除通话过程中的杂音和回音

二.fm23回声消除驱动程序示例

//#include <linux/i2c/fm1288.h>
//#include <linux/sensors.h>
#include <linux/pinctrl/consumer.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
#include <linux/i2c/at24.h>
#include <linux/fs.h>
#define FM23_RESET GPIO_PC(25)
unsigned char fm23_init_data[] = {
0xC0,
0xFC, 0xF3, 0x3B, 0x1E, 0x50, 0x00, 0x18,
0xFC, 0xF3, 0x3B, 0x1E, 0x52, 0x00, 0x00,
0xFC, 0xF3, 0x3B, 0x1E, 0x6F, 0x00, 0x03,
0xFC, 0xF3, 0x3B, 0x1E, 0x72, 0x80, 0x02,
0xFC, 0xF3, 0x3B, 0x1E, 0x82, 0x01, 0x01,
0xFC, 0xF3, 0x3B, 0x1E, 0x84, 0x03, 0x12,
0xFC, 0xF3, 0x3B, 0x1E, 0x85, 0x00, 0x00,
0xFC, 0xF3, 0x3B, 0x1E, 0x87, 0x00, 0x66,//哪一组mic配置db Para[0x1E87, Mic_pgagain]: bit[6:4] for mic1, bit[2:0] for mic
0xFC, 0xF3, 0x3B, 0x1E, 0x89, 0x00, 0x01,
0xFC, 0xF3, 0x3B, 0x1E, 0x8B, 0x02, 0x60,//7.5db 0x260 / 0x100 qu log * 2
0xFC, 0xF3, 0x3B, 0x1E, 0x8F, 0x00, 0x80,
0xFC, 0xF3, 0x3B, 0x1E, 0xA9, 0x00, 0x00,
0xFC, 0xF3, 0x3B, 0x1E, 0xAE, 0x01, 0x00,//信号幅度
0xFC, 0xF3, 0x3B, 0x1E, 0xB1, 0x40, 0x00,//阀值 设置为0 单一功能 通话是声音不能同事传输 最大为7fff
0xFC, 0xF3, 0x3B, 0x1E, 0xB2, 0x00, 0x00,
0xFC, 0xF3, 0x3B, 0x1E, 0xB8, 0x00, 0x01,//声音传输时间差
0xFC, 0xF3, 0x3B, 0x1E, 0xB9, 0x18, 0x00,
0xFC, 0xF3, 0x3B, 0x1E, 0xBB, 0x18, 0x00,
0xFC, 0xF3, 0x3B, 0x1E, 0xC7, 0x0A, 0x00,
0xFC, 0xF3, 0x3B, 0x1E, 0xC8, 0x08, 0x00,
0xFC, 0xF3, 0x3B, 0x1E, 0xED, 0x04, 0x00,//消除噪音 值最大不消噪
0xFC, 0xF3, 0x3B, 0x1E, 0xEF, 0x08, 0x00,
0xFC, 0xF3, 0x3B, 0x1F, 0x03, 0x00, 0x05,
0xFC, 0xF3, 0x3B, 0x1F, 0x32, 0x00, 0x10,
0xFC, 0xF3, 0x3B, 0x1F, 0x33, 0x00, 0x09,
0xFC, 0xF3, 0x3B, 0x1F, 0x36, 0x00, 0x03,
0xFC, 0xF3, 0x3B, 0x1F, 0x4D, 0x18, 0x00,//频域 这个值越大声音收入就越小(主)
0xFC, 0xF3, 0x3B, 0x1F, 0x4E, 0x01, 0x00,//频域 这个值越大声音收入就越小
0xFC, 0xF3, 0x3B, 0x1F, 0x4F, 0x04, 0x00,
0xFC, 0xF3, 0x3B, 0x1F, 0x50, 0x02, 0x00,
0xFC, 0xF3, 0x3B, 0x1F, 0x53, 0x68, 0x00,
0xFC, 0xF3, 0x3B, 0x1F, 0x5C, 0x0A, 0x00,
0xFC, 0xF3, 0x3B, 0x1F, 0x5D, 0x32, 0xF5,//闲置的时候喇叭还有噪音 值越大压制的越小
0xFC, 0xF3, 0x3B, 0x1F, 0x5F, 0x6A, 0x00,
0xFC, 0xF3, 0x3B, 0x1F, 0x0B, 0x10, 0x00,
0xFC, 0xF3, 0x3B, 0x1E, 0x83, 0x2D, 0x79,
0xFC, 0xF3, 0x3B, 0x1E, 0x88, 0x0C, 0xB0,
0xFC, 0xF3, 0x3B, 0x1E, 0xEE, 0x0B, 0x05,//噪音 值越大抑制越厉害
0xFC, 0xF3, 0x3B, 0x1F, 0x24, 0x00, 0x00,
0xFC, 0xF3, 0x3B, 0x1F, 0x34, 0x60, 0x00,
0xFC, 0xF3, 0x3B, 0x1F, 0x37, 0x78, 0x00,
0xFC, 0xF3, 0x3B, 0x1F, 0x38, 0x24, 0x00,
0xFC, 0xF3, 0x3B, 0x1F, 0x39, 0x06, 0x00,
0xFC, 0xF3, 0x3B, 0x1F, 0x3A, 0x18, 0x00,
0xFC, 0xF3, 0x3B, 0x1E, 0xA7, 0x7F, 0xFF,
0xFC, 0xF3, 0x3B, 0x1E, 0x42, 0x00, 0x22,
0xFC, 0xF3, 0x3B, 0x1E, 0x75, 0x00, 0x00
};
unsigned char fm23_read_data1[7] = {
0xC0,
0xFC, 0xF3, 0x37, 0x1E, 0x83
};
unsigned char fm23_read_data2[6] = {
0xC0,
0xFC, 0xF3, 0x60, 0x25,
};
unsigned char fm23_read_data3[2] = {
0xFF
};
unsigned char fm23_read_data4[6] = {
0xC0,
0xFC, 0xF3, 0x60, 0x26,
};
unsigned char fm23_read_data5[2] = {
0xFF
};
struct fm23_data {
struct i2c_client *client;
// struct sensors_classdev cdev;
struct class *fm23_class;
struct device *factory_device;
int reset_gpio;
u32 reset_gpio_flags;
struct pinctrl *fm23_pinctrl;
struct pinctrl_state *pinctrl_state_default;
struct regulator *vdd;
};
static struct fm23_data fm23 = NULL;
/

  • This parameter is to help this driver avoid blocking other drivers out

  • of I2C for potentially troublesome amounts of time. With a 100 kHz I2C

  • clock, one 256 byte read takes about 1/43 second which is excessive;

  • but the 1/170 second it takes at 400 kHz may be quite reasonable; and

  • at 1 MHz (Fm+) a 1/430 second delay could easily be invisible.

  • This value is forced to be a power of two so that writes align on pages.
    */
    static unsigned io_limit = 128;
    module_param(io_limit, uint, 0);
    MODULE_PARM_DESC(io_limit, “Maximum bytes per I/O (default 128)”);
    #define I2C_ADAPTER_ID 0
    static struct i2c_client *device_client;
    static struct at24_platform_data fm23_382 = {
    .byte_len = (256 * 8 * 8) / 8,
    .page_size = 16,
    };
    static struct i2c_board_info i2c_info[] __initdata = {
    {
    I2C_BOARD_INFO(“fm23”, 0x60),
    .platform_data = &fm23_382,
    },
    };
    static int fm23_i2c_init(void)
    {
    int ret = -1;
    struct i2c_msg msgs[] = {
    {
    .addr = 0x60,
    .flags = 0,
    .len = sizeof(fm23_init_data),
    .buf = fm23_init_data,
    },
    };
    if(fm23 != NULL)
    {
    int i = 0;
    for(i = 0; i< 3; i ++){
    ret = i2c_transfer(fm23->client->adapter, msgs, 1);
    if (ret < 0)
    dev_err(&fm23->client->dev, “%s: i2c write error.\n”, func);
    }
    printk(“%s: ret = %d\n”, func, ret);
    if(ret > 0)
    return 0;
    }
    return ret;
    }
    static int fm23_probe(struct i2c_client *client, const struct i2c_device_id id)
    {
    int err = 0;
    printk(“fm23_probe\n”);
    dev_info(&client->dev, “fm23_probe”);
    if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
    printk(KERN_ERR “SENODIA fm23_probe: check_functionality failed.\n”);
    err = -ENODEV;
    goto exit0;
    }
    /
    Allocate memory for driver data */
    fm23 = kzalloc(sizeof(struct fm23_data), GFP_KERNEL);
    if (!fm23) {
    printk(KERN_ERR “SENODIA fm23_probe: memory allocation failed.\n”);
    err = -ENOMEM;
    goto exit0;
    }
    fm23->client = client;
    i2c_set_clientdata(client, fm23);
    // if (client->dev.of_node) {
    // err = fm23_parse_dt(&client->dev);
    // if (err) {
    // dev_err(&client->dev, “DT parsing failed, err = %d\n”, err);
    // goto err_parse_dt;
    // }
    // }
    fm23->reset_gpio = FM23_RESET;
    if(fm23->reset_gpio < 0)
    goto exit0;
    err = gpio_request_one(fm23->reset_gpio,GPIOF_OPEN_SOURCE ,“fm23 reset”);
    if (err) {
    dev_err(&client->dev, “Could not request pin %d for GPIO.\n”, fm23->reset_gpio);
    return -EIO;
    }
    gpio_direction_output(fm23->reset_gpio, 1);
    msleep(20);
    err = fm23_i2c_init();
    if(err){
    dev_err(&client->dev, “fm23 init failed,err = %d\n”, err);
    goto exit0;
    }
    printk(“fm23_init scuess\n”);

    return err;
    exit0:
    if(fm23 != NULL)
    {
    kfree(fm23);
    fm23 = NULL;
    }
    printk(“fm23_init fail\n”);
    return err;
    }
    static int fm23_remove(struct i2c_client client)
    {
    return 0;
    }
    static struct of_device_id fm23_match_table[] = {
    { .compatible = “fortemedia,fm23”, },
    { },
    };
    MODULE_DEVICE_TABLE(of, fm23_match_table);
    static const struct i2c_device_id fm23_id_table[] = {
    { “fm23”, 0 },
    { },
    };
    MODULE_DEVICE_TABLE(i2c, fm23_id_table);
    static struct i2c_driver fm23_driver = {
    .probe = fm23_probe,
    .remove = fm23_remove,
    .id_table = fm23_id_table,
    .driver = {
    .name = “fm23”,
    .owner = THIS_MODULE,
    .of_match_table = fm23_match_table,
    },
    };
    static int __init fm23_init(void)
    {
    int ret = -1;
    printk("fm23_ts_init
    *************\n");
    ret = i2c_add_driver(&fm23_driver);
    printk(“i2c_add_driver = %d**************************\n” , ret);
    return ret;
    }
    static void __exit fm23_exit(void)
    {
    i2c_del_driver(&fm23_driver);
    }
    late_initcall(fm23_init);
    module_exit(fm23_exit);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值