资讯详情

AW9523 linux 按键驱动解析

AW9523 linux 按键驱动分析

硬件介绍

AW9523是国产芯片,中文手册看起来方便多了。datasheet以下是编写驱动过程中的一些重要信息。当然,最好看芯片手册和项目使用AW9523接入16个独立按钮。

AW9523A 是一款 I2C 接口、 4 路呼吸灯及 16 路扩展 GPIO 它包含的控制器 16 路双向 GPIO 端口,其中 4 道路可通过指令配置LED 驱动模式。

寄存器地址 W/R 默认值 功能 描述
00H R xxH Input_Port0 P0 口输入状态
01H R xxH Input_Port1 P1 口输入状态
02H W/R 参考表 2 Output_Port0 P0 口输出状态
03H W/R 参考表 2 Output_Port1 P1 口输出状态
04H W/R 00H Config_Port0 P0 口输入或输出配置
05H W/R 00H Config_Port1 P1 口输入或输出配置
06H W/R 00H Int_Port0 P0 口中断使能
07H W/R 00H Int_Port1 P1 口中断使能
11H W/R 00H CTL 全局控制寄存器
13H W/R 0FH LED Mode Switch P1_3~P1_0 切换工作模式
20H W 00H DIM0 P1_0 口 LED 电流控制
21H W 00H DIM1 P1_1 口 LED 电流控制
22H W 00H DIM2 P1_2 口 LED 电流控制
23H W 00H DIM3 P1_3 口 LED 电流控制
7FH W 00H Software Reset 软复位寄存器
08H~10H 12H 14H~1FH 24H~7EH 80H~FFH - - - 用户寄存器,用户不操作

注册设备

AW9523使用i2c_driver模型,在board中对应I2C i2c_board_info注册设备如下,这里设备AW9523的AD0/AD管脚应接地。从上图可以确定I2C地址。

#if defined(CONFIG_AW9523_KPD)     {         I2C_BOARD_INFO("aw9523", 0xB0),     }, #endif

驱动

probe函数

aw9523上电复位,代码如下

      // power on   gpio_request(rst, "aw9523_rst");   gpio_direction_output(rst, 0);   udelay(100);   gpio_direction_output(rst, 1);   mdelay(100);   gpiofree(rst);

检测ID,代码如下

err = aw9523_read(data->client, 0x10, &val);
if (!err && val == 0x23)
    return 0;

初始化配置,代码如下

	// port 0 input mode
	aw9523_write(data->client, AW9523_CONFIG_PORT_0, 0xff);	// keys input
	// port 0 output low
	aw9523_write(data->client, AW9523_OUTPUT_PORT_0, 0x00);
	// port 0 enable int
	aw9523_write(data->client, AW9523_INT_PORT_0, 0x00);	// enable irq

	// port 1 input mode
	aw9523_write(data->client, AW9523_CONFIG_PORT_1, 0xff);	// keys input
	// port 1 output low
	aw9523_write(data->client, AW9523_OUTPUT_PORT_1, 0x00);
	// port 1 enable int
	aw9523_write(data->client, AW9523_INT_PORT_1, 0x00);	// enable irq

注册输入设备


	input = input_allocate_device();
	if (!input) {
		err = -ENOMEM;
		goto exit_input_dev_alloc_failed;
	}

	input_set_drvdata(input, data);

	for(i=0; i<8*2; i++) {
		input_set_capability(input, EV_KEY, data->key_matrix[i]);
	}

	err = input_register_device(input);
	if (err) {
		goto exit_input_register_device_failed;
	}

创建工作队列

	INIT_WORK(&data->work, aw9523_work_func);
	data->work_q = create_singlethread_workqueue(dev_name(&client->dev));
	if (!data->work_q) {
		err = -ESRCH;
		goto exit_create_singlethread_failed;
	}
	schedule_work(&data->work);

申请中断,aw9523中断管教是连接到我们CPU上的,所以有按键按下,会触发中断

	err = request_irq(client->irq, aw9523_irq_handler, IRQF_TRIGGER_FALLING, client->name, data);
	if (err < 0) {
		dev_err(&client->dev, "aw9523_i2c_probe: request irq failed\n");
		goto exit_irq_request_failed;
	}

中断服务函数

中断服务函数比较简单,只需要关闭AW9523中断,将工作加入到工作队列中,最终唤醒对应内核线程

	aw9523_irq_disable(data);

	if (!work_pending(&data->work))
		queue_work(data->work_q, &data->work);
	return IRQ_HANDLED;

工作函数

工作函数读取AW9523 P0 P1口的管教状态,进行比对新旧状态比对,找到变化的管教,通过input系统上报。

	// get port0 value
	aw9523_read(data->client, AW9523_INPUT_PORT_0, &p0);
	p0 = ~p0;
	if(p0 != data->port0_state) {
		chg = p0^data->port0_state;	// xor
		tmp = p0;
		for(i=0; i<8; i++) {
			if(chg & 0x01) {
	                    input_report_key(data->input_dev, data->key_matrix[i], tmp & 0x01);
	                    input_sync(data->input_dev);
			}
			chg >>= 1;
			tmp >>= 1;
		}
		data->port0_state = p0;
	}

 

标签: aw连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台