天天看點

在kernel裡添加一個i2c外圍裝置

在kernel裡添加一個已知晶片位址的外圍裝置的驅動,主要包含申請注冊使用等

1. 定義主要變量:

static struct i2c_client *key_ic_client;

static struct i2c_board_info key_ic_info = {
	/*  0x11 is the slave ic addr  */
	I2C_BOARD_INFO("carplay_key_ic", 0x11),
};
           

2. 注冊申請i2c外圍裝置:

struct i2c_adapter *i2c_adap;

	printk(KERN_ALERT "%s\n", __func__);

	i2c_adap = i2c_get_adapter(5);  // i2c_5
	if (i2c_adap == NULL) {
		printk(KERN_ERR "%s No adapter available!\n", __func__);
		return 0;
	}

	key_ic_client = i2c_new_device(i2c_adap, &key_ic_info);
	if (NULL == key_ic_client) {
		printk(KERN_ERR "%s i2c_new_device is Err!\n", __func__);
		return 0;
	}

	if (i2c_adap) {
		printk(KERN_ERR "%s i2c_adap is OK!\n", __func__);
		i2c_put_adapter(i2c_adap);
	}
           

3. 使用寫函數向寄存器寫入資料:

      不同的i2c晶片要求的寫函數,未必一樣,要根據晶片的資料手冊,來決定使用什麼樣的kernel裡的寫入驅動函數;

int ret = 0;

		ret = i2c_smbus_write_byte_data(key_ic_client, 0x10, 0x33);
		if (ret < 0)
		{
			printk(KERN_ERR "%s: i2c_smbus_write_byte_data err\n", __func__);
		}
           

4. 使用讀函數讀取寄存器裡的資料:

      不同的i2c晶片要求的讀函數,未必一樣,要根據晶片的資料手冊,來決定使用什麼樣的kernel裡的讀取驅動函數;

i2c_smbus_write_byte(key_ic_client, 0x00);
		udelay(500);  // this delay is Necessary
		value = i2c_smbus_read_byte(key_ic_client);
		printk(KERN_ALERT "%s: value = 0x%x\n", __func__, value);
           

      這個例子中,讀取函數之間有延時,是因為,這個晶片來不及處理讀取請求,需要延時一段時間,再讀取。大部分晶片不需要這種延時。

I2C