레이블이 cp210x인 게시물을 표시합니다. 모든 게시물 표시
레이블이 cp210x인 게시물을 표시합니다. 모든 게시물 표시

2012년 1월 16일 월요일

linux cp2104 driver

CP2104 USB to Serial를 사용하는데 ubuntu에서 minicom이 안되는 문제가 있다.

찾아 보니 CP210x driver에 baudrate 초기화 버그가 있는 듯...

http://www.spinics.net/lists/linux-usb/msg56969.html

그래서 driver patch를 적용하여 보겠습니다.

자신이 사용하는 kernel 버전을 확인한다.

커널 버전 확인
$uname -a
Linux codewalker-desktop 2.6.32-38-generic #83-Ubuntu SMP Wed Jan 4 11:12:07 UTC 2012 x86_64 GNU/Linux


synaptic에서 desktop kernel source를 받는다.

linux-source, linux-source-2.6.32

아래 path로 소스 파일이 받아 진다.

/usr/src/linux-source-2.6.32.tar.bz2

/usr/src/linux-source-2.6.32/drivers/usb/serial/cp210x.c 수정한다.

 diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 3835106..dcba930 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -201,6 +201,8 @@ static struct usb_serial_driver cp210x_device = {
 #define CP210X_EMBED_EVENTS 0x15
 #define CP210X_GET_EVENTSTATE 0x16
 #define CP210X_SET_CHARS 0x19
+#define CP210X_GET_BAUDRATE 0x1d
+#define CP210X_SET_BAUDRATE 0x1e
 
 /* CP210X_IFC_ENABLE */
 #define UART_ENABLE  0x0001
@@ -459,16 +461,12 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
  unsigned int *cflagp, unsigned int *baudp)
 {
  unsigned int cflag, modem_ctl[4];
- unsigned int baud;
+ u32 baud;
  unsigned int bits;
 
  dbg("%s - port %d", __func__, port->number);
 
- cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2);
- /* Convert to baudrate */
- if (baud)
-  baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud);
-
+ cp210x_get_config(port, CP210X_GET_BAUDRATE, &baud, sizeof(baud));
  dbg("%s - baud rate = %d", __func__, baud);
  *baudp = baud;
 
@@ -580,7 +578,8 @@ static void cp210x_set_termios(struct tty_struct *tty,
   struct usb_serial_port *port, struct ktermios *old_termios)
 {
  unsigned int cflag, old_cflag;
- unsigned int baud = 0, bits;
+ u32 baud;
+ unsigned int bits;
  unsigned int modem_ctl[4];
 
  dbg("%s - port %d", __func__, port->number);
@@ -595,8 +594,8 @@ static void cp210x_set_termios(struct tty_struct *tty,
  /* If the baud rate is to be updated*/
  if (baud != tty_termios_baud_rate(old_termios) && baud != 0) {
   dbg("%s - Setting baud rate to %d baud", __func__, baud);
-  if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV,
-     ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) {
+  if (cp210x_set_config(port, CP210X_SET_BAUDRATE,
+       &baud, sizeof(baud))) {
    dbg("Baud rate requested not supported by device");
    baud = tty_termios_baud_rate(old_termios);
   }
-- 
 

$sudo make menuconfig


$sudo make -j10


kernel 빌드 시 에러가 발생 아래와 같이 수정.


ERROR-2
LD [M]  ubuntu/omnibook/omnibook.o
ld: /ubuntu/omnibook/sections.lds: No such file: No such file or directory
make[2]: *** [ubuntu/omnibook/omnibook.o] Error 1
make[1]: *** [ubuntu/omnibook] Error 2
make: *** [ubuntu] Error 2
SOLUTION-2
$ sudo vi /usr/src/linux/ubuntu/omnibook/Makefile
160: #EXTRA_LDFLAGS +=  $(src)/sections.lds
161: EXTRA_LDFLAGS += $(PWD)/ubuntu/omnibook/sections.lds


http://thangamaniarun.wordpress.com/2010/07/08/how-to-quickly-build-custom-kernel-on-ubuntu-10-04/




cp210x.ko module 만들기


$sudo make modules


$sudo make modules_install



[/lib/modules]$ ls -l
합계 20
drwxr-xr-x 4 root root 4096 2010-04-29 21:45 2.6.32-21-generic
drwxr-xr-x 5 root root 4096 2011-12-16 18:47 2.6.32-36-generic
drwxr-xr-x 5 root root 4096 2012-01-17 16:24 2.6.32-37-generic
drwxr-xr-x 5 root root 4096 2012-01-24 17:09 2.6.32-38-generic
drwxr-xr-x 3 root root 4096 2012-01-25 17:54 2.6.32.52+drm33.21



kernel 소스 Makefile에 EXTRAVERSION이 실제 설치된 kernel과 틀리다.


그래서 수동으로 cp210x.ko를 2.6.32-38-generic 폴더 밑에 파일로 바꿔주면 된다.


EXTRAVERSION이 다르지만 insmod나 hot-plugin시 문제 없이 module이 올라 간다.


혹시나 드라이버에 문제가 생기면 동일한 linux-image-generic를 synaptic에서 재설치해 주면 해결된다.


module의 EXTRAVERSION을 확인하기 위해서는 modinfo를 이용하면 된다.



alias:          usb:v0FCFp1004d*dc*dsc*dp*ic*isc*ip*
alias:          usb:v0FCFp1003d*dc*dsc*dp*ic*isc*ip*
alias:          usb:v0BEDp1101d*dc*dsc*dp*ic*isc*ip*
alias:          usb:v0BEDp1100d*dc*dsc*dp*ic*isc*ip*
alias:          usb:v08FDp000Ad*dc*dsc*dp*ic*isc*ip*
alias:          usb:v08E6p5501d*dc*dsc*dp*ic*isc*ip*
alias:          usb:v0745p1000d*dc*dsc*dp*ic*isc*ip*
alias:          usb:v0489pE000d*dc*dsc*dp*ic*isc*ip*
alias:          usb:v0471p066Ad*dc*dsc*dp*ic*isc*ip*
alias:          usb:v045Bp0053d*dc*dsc*dp*ic*isc*ip*
depends:        usbserial
vermagic:       2.6.32.52+drm33.21 SMP mod_unload modversions 
parm:           debug:Enable verbose debugging messages (bool)
[/lib/modules/2.6.32-38-generic/kernel/drivers/usb/serial]$