am335x i2c_max7359-IC按键与旋钮驱动

20160719

I2C驱动开发总结

 

. I2C设备驱动代码示例

1.1 源代码

1.1.1 max7359_keypad.c

/* max7359_keypad.c - MAX7359 Key Switch Controller Driver */

#include <linux/module.h>

#include <linux/gpio.h>

#include <linux/i2c.h>

#include <linux/slab.h>

#include <linux/interrupt.h>

#include <linux/pm.h>

#include <linux/input.h>

#include <linux/input/matrix_keypad.h>

#include <linux/delay.h>

 

#define MAX7359_MAX_KEY_ROWS 8

#define MAX7359_MAX_KEY_COLS 8

#define MAX7359_MAX_KEY_NUM (MAX7359_MAX_KEY_ROWS * MAX7359_MAX_KEY_COLS)

#define MAX7359_ROW_SHIFT 3

 

/*

 * MAX7359 registers

 */

#define MAX7359_REG_KEYFIFO 0x00

#define MAX7359_REG_CONFIG 0x01

#define MAX7359_REG_DEBOUNCE 0x02

#define MAX7359_REG_INTERRUPT 0x03

#define MAX7359_REG_PORTS 0x04

#define MAX7359_REG_KEYREP 0x05

#define MAX7359_REG_SLEEP 0x06

 

/*

 * Configuration register bits

 */

#define MAX7359_CFG_SLEEP (1 << 7)

#define MAX7359_CFG_INTERRUPT (1 << 5)

#define MAX7359_CFG_KEY_RELEASE (1 << 3)

#define MAX7359_CFG_WAKEUP (1 << 1)

#define MAX7359_CFG_TIMEOUT (1 << 0)

 

/*

 * Autosleep register values (ms)

 */

#define MAX7359_AUTOSLEEP_8192 0x01

#define MAX7359_AUTOSLEEP_4096 0x02

#define MAX7359_AUTOSLEEP_2048 0x03

#define MAX7359_AUTOSLEEP_1024 0x04

#define MAX7359_AUTOSLEEP_512 0x05

#define MAX7359_AUTOSLEEP_256 0x06

 

#if 1

#define PRINTK_C(fmt, args...) printk(KERN_INFO#fmt, ##args)

#else

#define PRINTK_C(fmt, args...)

#endif

 

struct max7359_keypad {

/* matrix key code map */

unsigned short keycodes[MAX7359_MAX_KEY_NUM];

struct input_dev *input_dev;

struct i2c_client *client;

 

    /* +++ Added by XXXX2013-09-04 +++ */

    unsigned long last_jiffies;

    int bCrA;

    int bCrB;

    int bCwA;

    int bCwB;

    /* --- Added by XXXX2013-09-04 --- */

};

 

static int max7359_write_reg(struct i2c_client *client, u8 reg, u8 val)

{

int ret = i2c_smbus_write_byte_data(client, reg, val);

 

if (ret < 0)

dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n",

__func__, reg, val, ret);

return ret;

}

 

static int max7359_read_reg(struct i2c_client *client, int reg)

{

int ret = i2c_smbus_read_byte_data(client, reg);

 

if (ret < 0)

dev_err(&client->dev, "%s: reg 0x%x, err %d\n",

__func__, reg, ret);

return ret;

}

 

static void max7359_build_keycode(struct max7359_keypad *keypad,

const struct matrix_keymap_data *keymap_data)

{

struct input_dev *input_dev = keypad->input_dev;

int i;

 

for (i = 0; i < keymap_data->keymap_size; i++) {

unsigned int key = keymap_data->keymap[i];

unsigned int row = KEY_ROW(key);

unsigned int col = KEY_COL(key);

unsigned int scancode = MATRIX_SCAN_CODE(row, col,

MAX7359_ROW_SHIFT);

unsigned short keycode = KEY_VAL(key);

 

/*设置扫描码与按键码对应,并标记按键码为下标的数组位为1*/

keypad->keycodes[scancode] = keycode;

__set_bit(keycode, input_dev->keybit);

}

__clear_bit(KEY_RESERVED, input_dev->keybit);

}

 

/* runs in an IRQ thread -- can (and will!) sleep */

static irqreturn_t max7359_interrupt(int irq, void *dev_id)

{

struct max7359_keypad *keypad = dev_id;

struct input_dev *input_dev = keypad->input_dev;

    int val, row, col, release, code, i;

 

    /* Modified by XXXX2013-08-30 Clear FIFO of MAX7359. */

    i = 16;

    do {

        val = max7359_read_reg(keypad->client, MAX7359_REG_KEYFIFO);

 

        row = val & 0x7;

        col = (val >> 3) & 0x7;

        release = val & 0x40;

        code = MATRIX_SCAN_CODE(row, col, MAX7359_ROW_SHIFT);

 

        PRINTK_C("[MAX7359]val:0x%02X row:%d col:%d, release:%d\n", val, row, col, release);

 

        if ((val < 0) || (0 == (val & 0xC0))) {

            return IRQ_HANDLED;

        }

 

        input_event(input_dev, EV_MSC, MSC_SCAN, code);

        input_report_key(input_dev, keypad->keycodes[code], !release);

        input_sync(input_dev);

    } while (i--);

 

return IRQ_HANDLED;

}

 

#define MAX7359_DEBOUNCE_JIFFIES    msecs_to_jiffies(10)

 

/* +++ Added

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值