//------------------------------------------------------------------------------ // // 파 일 : i2c_api.c // 설 명 : I2C DEVICE DRIVE API LIB // // 작 성 : 유영창 frog@falinux.com //------------------------------------------------------------------------------ #include #include #include #include #include #include #include #include #include #include #include #include //------------------------------------------------------------------------------ // 설명 : 매크로 상수 #define I2C_MAX_BUS 8 //------------------------------------------------------------------------------ // 설명 : 전역변수 static i2c_bus_t ds[I2C_MAX_BUS]; // I2C 디바이스 드라이버 관리 구조체 static int i2c_bus_cnt = 0; // 시스템에 존재하는 I2C 버스 수 //------------------------------------------------------------------------------ // 설명 : pcmcia 디바이스 드라이버 주번호를 얻는다. // 매계 : major : 함수 실행 성공시 주번호를 전달한다. // 반환 : I2C_OK : major 번호를 얻었다. // I2C_NOT_FIND_MAJOR : major 번호를 발견하지 못했다. // 주의 : //------------------------------------------------------------------------------ int i2c_get_major_i2c( int *major ) { FILE *fp; char linebuff[128]; char device_name[32]; int tmp_major; fp = fopen("/proc/devices", "r"); if(fp == NULL) return I2C_NOT_FIND_MAJOR; while(1) { if( fgets(linebuff, sizeof( linebuff) , fp ) == NULL ) break; if (sscanf(linebuff, "%d %s", &tmp_major, device_name) == 2) { if (strcmp("i2c", device_name) == 0) { *major = tmp_major; fclose( fp ); return I2C_NO_ERROR; } } } fclose( fp ); return I2C_NOT_FIND_MAJOR; } //------------------------------------------------------------------------------ // 설명 : I2C 버스 디바이스 파일을 만들고 연다. //------------------------------------------------------------------------------ int i2c_make_bus_node( int major, int bn ) { sprintf(ds[bn].node_fname, "/dev/i2cbus%d-%d", getpid(), bn ); mknod(ds[bn].node_fname, (S_IRWXU|S_IRWXG|S_IFCHR), (major<<8) + bn ); ds[bn].fd = open(ds[bn].node_fname, O_RDWR ); // printf( "%s ds[%d].fd = %d\n", ds[bn].node_fname, bn, ds[bn].fd ); unlink(ds[bn].node_fname); return ds[bn].fd; } //------------------------------------------------------------------------------ // 설명 : I2C API 를 초기화 한다. //------------------------------------------------------------------------------ int i2c_init( void ) { int major; int ret; int lp; ret = i2c_get_major_i2c( &major ); if( I2C_NOT_FIND_MAJOR == ret ) { printf( "can't find nodfile\n" ); return -1; } //printf( "I2C Major Numner = %d\n", major ); i2c_bus_cnt = 0; for( lp = 0; lp < I2C_MAX_BUS; lp++ ) { if( i2c_make_bus_node( major, lp ) >= 0 ) { i2c_bus_cnt++; } else { ds[lp].fd = -1; } } return 0; } //------------------------------------------------------------------------------ // 설명 : 현재 존재하는 I2C BUS 수를 얻는다. // 반환 : 소켓 수 //------------------------------------------------------------------------------ int i2c_get_bus_count( void ) { return i2c_bus_cnt; } //------------------------------------------------------------------------------ // 설명 : I2C 버스에서 읽는다. //------------------------------------------------------------------------------ int i2c_read_data( access_data_t * access_data ) { if( ds[access_data->bus].fd < 0 ) return I2C_NOT_FIND_BUS; if( access_data->size > sizeof( access_data->data ) ) access_data->size = sizeof( access_data->data ); ioctl( ds[access_data->bus].fd, I2C_SLAVE, access_data->addr ); access_data->size = read( ds[access_data->bus].fd, access_data->data, access_data->size ); if( access_data->size < 0 ) return I2C_READ_DEVICE; return I2C_NO_ERROR; } //------------------------------------------------------------------------------ // 설명 : I2C 버스에 데이터를 써 넣는다. //------------------------------------------------------------------------------ int i2c_write_data( access_data_t * access_data ) { if( ds[access_data->bus].fd < 0 ) return I2C_NOT_FIND_BUS; if( access_data->size > sizeof( access_data->data ) ) access_data->size = sizeof( access_data->data ); ioctl( ds[access_data->bus].fd, I2C_SLAVE, access_data->addr ); access_data->size = write( ds[access_data->bus].fd, access_data->data, access_data->size ); if( access_data->size < 0 ) return I2C_WRITE_DEVICE; return I2C_NO_ERROR; }