본문 바로가기

Programming/Linux_Kernel

linux 에서 GPIO로 I2C Emulation 사용하기


mach-모델명.h code 에서 에뮬레이션 i2c device 등록
#define GPIO_TOUCH_SDA   S3C64XX_GPC(5)

static struct i2c_gpio_platform_data i2c_touch_platdata = {
 .sda_pin = GPIO_TOUCH_SDA, // gpio number
 .scl_pin = GPIO_TOUCH_SCL,
 .udelay  = 2,
 .sda_is_open_drain = 0,
 .scl_is_open_drain = 0,
 .scl_is_output_only = 0
};

static struct platform_device sec_device_i2c_touch = {
 .name = "i2c-gpio",
 .id  = 4, // adepter number
 .dev.platform_data = &i2c_touch_platdata,
};

해당 i2c 를 사용할 device 에서 adepter 를 불러서 등록
static int __init tsp_probe(struct platform_device *pdev)
{
setup.i2c_address = (TSP_SENSOR_ADDRESS);
 setup.i2c_bus = 4;
ret = touch_add_i2c_device(&setup);
}


static const struct i2c_device_id touch_i2c_id[] = {
 { "touch I2C", 0 },
 { }
};

//MODULE_DEVICE_TABLE(i2c, touch_i2c_id); // 에뮬레이션 시는 필요 없음

static struct i2c_driver touch_i2c_driver = {
 .driver = {
  .name = "touch I2C",
  .owner = THIS_MODULE,
 },
 .probe =    touch_i2c_probe,
 .remove =   touch_i2c_remove,
 .id_table = touch_i2c_id,
};

int touch_add_i2c_device(const struct touch_setup_data *setup)
{
 struct i2c_board_info info;
 struct i2c_adapter *adapter;
 int ret;
 ret = i2c_add_driver(&touch_i2c_driver);
 if (ret != 0) {
  printk("[TSP][ERR] can't add i2c driver\n");
  return ret;
 }

 memset(&info, 0, sizeof(struct i2c_board_info));
 info.addr = setup->i2c_address;
 strlcpy(info.type, "touch", I2C_NAME_SIZE);

 adapter = i2c_get_adapter(setup->i2c_bus);
 if (!adapter) {
  printk("[TSP][ERR] can't get i2c adapter %d\n", setup->i2c_bus);
  goto err_driver;
 }
 // cypress touch device have to get individual scl setting function.
// adapter->algo_data = &ioc_data;
 g_client = i2c_new_device(adapter, &info);
 g_client->adapter->timeout = 0;
 g_client->adapter->retries = 0;
 
 i2c_put_adapter(adapter);
 if (!g_client) {
  printk("[TSP][ERR] can't add i2c device at 0x%x\n",
   (unsigned int)info.addr);
  goto err_driver;
 }
 return 0;

err_driver:
 i2c_del_driver(&touch_i2c_driver);
 return -ENODEV;
}