기존 이솝 임베디드 포럼의 지식인 서비스가 게시판 형태로 변경되었습니다.

현재 Odroid상에 자이로 센서를 붙일려고 합니다. 그래서 새롭게 추가 할려는 자이로 센서의 I2C device driver를 module

로 작성하여 등록 할려고 합니다. 일단 제가 여기 저기 찾아 보면서 만든 방법과 등록 절차가 맞는지 검토좀 해 주셨으면 합니다. 혼자 하다보니...도무지 물어 볼데도 없고 답답합니다.

이것저것 보고 하다 보니 아래 함수명 들이 좀 맞지는 않지만 좀 봐 주셨으면 합니다.

 

1. arch/arm/mach-s5pc100/mach-hkdkc100.c 파일에 아래 내용 추가

static struct i2c_board_info i2c_devs0[] __initdata = {
 { I2C_BOARD_INFO("max17040", 0x36), },
 { I2C_BOARD_INFO("max8698c", 0x66), },
 { I2C_BOARD_INFO("atmega8", 0x38), }, //hwang
};

 

2.  1번에 등록한 atmega8 이라는 device driver 작성

 

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/clk.h>
#include <linux/mutex.h>
#include <linux/gpio.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/uaccess.h>

#include <plat/regs-gpio.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-bank-h0.h>

#include <mach/map.h>
#include <asm/mach/irq.h>

///
//#include <linux/module.h>
#include <linux/bug.h>
#include <linux/err.h>
#include <linux/i2c.h>


struct atmega8_chip {
 struct device *dev;
 struct i2c_client *client;
 struct mutex io_lock;
 int num_regulators;
 struct regulator_dev **rdev;
 struct atmega8_platfrom_data *pdata;
};

static struct atmega8_chip *atmega8;

//Global variable
static int atmega8_usage = 0;

static unsigned char ucRegNum;

// define functions...
int atmega8_open (struct inode *minode, struct file *mfile);
ssize_t atmega8_write(struct file *, const char *, size_t, loff_t *);
ssize_t atmega8_read(struct file *, const char *, size_t, loff_t *);

int atmega8_release (struct inode *minode, struct file *mfile);

static const struct file_operations atmega8_fops =
{
 .open  = atmega8_open,
 .write  = atmega8_write,
 .read  = atmega8_read,
 .release = atmega8_release,
};


//static int atmega8_write_reg(struct i2c_client *client, u8 reg, u8 value)
static int atmega8_write_reg(u8 reg, u8 value)

{
 int ret;
 printk("atmega8_write_reg STARTrn");
 //ret = i2c_smbus_write_byte_data(client, reg, value);
 ret = i2c_smbus_write_byte_data(atmega8->client, reg, value);
 

 if(ret < 0)
  //dev_err(&client->dev, "%s:err %dn", __func__, ret);
  printk("err : %x rn", ret);
 printk("ret : %x rn", ret);
 return ret;
}

//static int atmega8_read_reg(struct i2c_client *client, u8 reg)
static int atmega8_read_reg(u8 reg)
{
 int ret;
 printk("atmega8_read_reg STARTrn");
 //ret = i2c_smbus_read_byte_data(client, reg);
 ret = i2c_smbus_read_byte_data(atmega8->client, reg);

 if(ret < 0)
  //dev_err(&client->dev, "%s:err %dn", __func__, ret);
  printk("err : %x rn", ret);
 printk("ret : %x rn", ret);
 return ret;
}

int atmega8_open (struct inode *minode, struct file *mfile)

 if (atmega8_usage != 0)
  return -EBUSY;

 atmega8_usage = 1;

 return 0;
}

int atmega8_release (struct inode *minode, struct file *mfile)
{
 atmega8_usage = 0;

 return 0;
}
ssize_t atmega8_write (struct file *file, const char *buffer, size_t length, loff_t * offset)
{
 //atmega8_write_reg(buffer[0], buffer[1]);
 ucRegNum = buffer[0];
 printk("address to read is %x (in write function)n", ucRegNum);

 return 0;
}

ssize_t atmega8_read (struct file *file, const char *buffer, size_t length, loff_t * offset)
{
 int iTemp;
 char *buff;

 
 printk("address to read is %x (in read function)n", ucRegNum);
 iTemp = atmega8_read_reg(ucRegNum);
 printk("value from i2c is %x n", iTemp);

 buff = kmalloc( 1, GFP_KERNEL );
 *buff = (unsigned char)iTemp;
 copy_to_user( buffer, buff, 1 );
 kfree ( buff );

 return 0;
}


static int __devinit atmega8_i2c_probe(struct i2c_client *client,
   const struct i2c_device_id *id)
{
 struct atmega8_chip *chip;
 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
 int ret;
 printk("atmega8_i2c_probe STARTrn");
 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
  return -EIO;

 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 if(!chip)
  return -ENOMEM;

 chip->client = client;
 chip->dev = &client->dev;
 chip->pdata = client->dev.platform_data;
 
 atmega8 = chip;
 //i2c_set_clientdata(client, chip);
 
 //mutex_init(&chip->io_lock);
 
  /* Detect MAX8698C */
  //ret = atmega8_read_reg(atmega8->client, 0);
  ret = atmega8_read_reg(0);
  printk("ret : %x rn", ret);
  if( ret < 0) {
   dev_err(&chip->dev, "failed to detect device n");
   goto err_detect;
  }
  i2c_set_clientdata(client, chip);
  printk("atmega8_i2c_probe OKrn");
  return 0;
 
 err_detect:
  printk("atmega8_i2c_probe ERRrn");
  i2c_set_clientdata(chip, NULL);
  kfree(chip);
 err:
  return ret;

}
static int __devexit atmega8_i2c_remove (struct i2c_client *client)
{
 struct atmega8_chip *chip = i2c_get_clientdata(client);


 kfree(chip->rdev);
 i2c_set_clientdata(chip, NULL);
 kfree(chip);

 return 0;
}

static const struct i2c_device_id atmega8_id[] = {
 {"atmega8", 0},
 { }
};
MODULE_DEVICE_TABLE(i2c, atmega8_id);

static struct i2c_driver atmega8_pmic_driver = {
 .driver = {
  .name = "atmega8",
  .owner = THIS_MODULE,
 },
 .probe = atmega8_i2c_probe,
 //.remove = atmega8_i2c_remove,
 .remove = __devexit_p(atmega8_i2c_remove),
 .id_table = atmega8_id,
};

static int __init atmega8_pmic_init(void)
{
 printk( "init module, HWANG2 n");
 i2c_add_driver(&atmega8_pmic_driver);
 
}
module_init(atmega8_pmic_init);

static void __exit atmega8_pmic_exit(void)
{
 i2c_del_driver(&atmega8_pmic_driver);
}
module_exit(atmega8_pmic_exit);

MODULE_AUTHOR("HWANG");
MODULE_LICENSE("GPL");

 

3. module 컴파일후 insmod 실행하여 모듈 추가

 

4. App에서 read, write 호출하여 사용

 

이렇게 4번까지 하려고 하는데 이렇게 하는게 맞는지 잘 모르겠어서요. 일반적으로 char device같은 경우 하나의 디바이스 파일 및에 하나의 device driver가 연결 되는데 지금과 같이 i2c-0 디바이스 파일 및에는 3개의 device driver가 붙은 격이 되는데 그럼.... App단에서 read, write함수를 호출하면 어느 device driver랑 연결이 되는지 애매해 보이거든요...

이렇게 작업을 하는게 맞는 건가요?

 


이제현

2010.05.04 04:13:35
*.120.74.180

전반적인 작업순서는 무난해 보입니다.


하나의 버스에 여러개의 장치가 붙어도 문제는 없습니다.

각 장치마다 고유한 어드레스가 있기 때문이죠...

추가하려는 장치의 I2C 디바이스 어드레스가 기존에 달려있는 다른 장치와 비교해 보세요.

ATMEGA8 MCU의 I2C Slave 주소만 주의하시면 될것 같네요.


사족입니다만, Java에서 디바이스 드라이버 read/write 하시려면, NDK로 JNI 하나 뚫어야 하고요..

List of Articles
번호 제목 글쓴이 날짜 조회 수sort
5608 6410 sleep mode 질문 드립니다. [1] 서비 2013-05-17 1670
5607 임베디드 리눅스를 보드에 타겟팅 했을 때 부팅이 되지 않는 이유는... [2] 혜민아빠 2012-03-07 1668
5606 이솝 2차 보드 나름대로 포팅 중 이해가 가지 않는 부분이 있습니... [7] 김영수 2008-01-30 1667
5605 텔레칩스 chip들에 관련 질문.... [3] 이성호 2009-07-24 1667
5604 현재 사용중인 하드웨어 추출 [2] dong880510 2014-04-07 1666
5603 잡담) 친절한 고현철님... 멍청한 나.... 지금 OTL중..... [1] 임장욱 2007-10-22 1665
5602 USB host와 gadget을 동시에 사용하는게 가능한가요? [2] 문철민 2012-05-17 1665
5601 WiFi EAP-FAST 관련 [1] 신현호 2014-04-02 1665
5600 안드로이드 터치 상하좌우 반전현상 [1] 나영찬 2011-08-03 1663
5599 고도리님 현재까지는 OpenCL은 동작은 ARM만 시킬 수 있습니다. ... [1] 김영준 2013-06-25 1663
5598 임베디드 리눅스 shutdown시에 필요한 전원 on상태의 유지시간? [2] 김민욱 2014-07-11 1663
5597 엑시노스 디코딩에 관련된 질문입니다. [3] seeman2 2012-02-19 1659
5596 gdb core dump 디버깅 질문 드립니다. [3] 석헌영 2009-09-30 1658
5595 Video와 network관련 문의드립니다. [4] 김경식 2013-06-27 1658
5594 비실시간 스케쥴링 관련 질문 드립니다. tezboy 2013-10-08 1658
5593 uboot 1.3.40을 쓰고 있는데요..파일시스템 40MB정도를 tftp를 통해... [3] 혜민아빠 2012-04-26 1656
5592 aesop-6410 board에서의 adb 사용 질문 [1] 김영문 2009-05-01 1656
5591 arm 보드에 APM 올리기 질문드립니다. [4] 은민아빠 2013-05-14 1656
» Odroid상에서 새로운 I2C device driver 등록하는방법 [1] 성빈아빠 2010-05-03 1654
5589 프로젝트 부품을 구하려하는데 조언부탁드립니다. [1] 시그인트 2014-02-27 1654

사용자 로그인