http://cafe.naver.com/embeddedcrazyboys
http://www.mangoboard.com/
SR130PC10 1.3M 카메라 포팅 가이드
베이스 소스는
으로 작업 했습니다.
$ vi arch/arm/mach-s5pv210/mach-mango210.c
#ifdef CONFIG_VIDEO_SR130PC10
#include <media/sr130pc10_platform.h>
#endif
#ifdef CONFIG_VIDEO_SR130PC10
static int sr130pc10_power_en_cam_A(int onoff)
{
int err;
/* Camera A */
if(onoff)
{
err = gpio_request(S5PV210_GPJ4(1), "GPJ4");
if (err)
printk(KERN_ERR "failed to request GPJ4 for CAM_2V8\n");
s3c_gpio_setpull(S5PV210_GPJ4(1), S3C_GPIO_PULL_NONE);
gpio_direction_output(S5PV210_GPJ4(1), 1);
gpio_free(S5PV210_GPJ4(1));
err = gpio_request(S5PV210_GPJ4(2), "GPJ4");
if (err)
printk(KERN_ERR "failed to request GPJ4 for CAM_2V8\n");
s3c_gpio_setpull(S5PV210_GPJ4(2), S3C_GPIO_PULL_NONE);
gpio_direction_output(S5PV210_GPJ4(2), 1);
gpio_free(S5PV210_GPJ4(2));
}
else
{
err = gpio_request(S5PV210_GPJ4(1), "GPJ4");
if (err)
printk(KERN_ERR "failed to request GPJ4 for CAM_2V8\n");
s3c_gpio_setpull(S5PV210_GPJ4(1), S3C_GPIO_PULL_NONE);
gpio_direction_output(S5PV210_GPJ4(1), 0);
gpio_free(S5PV210_GPJ4(1));
if (err)
printk(KERN_ERR "failed to request GPJ4 for CAM_2V8\n");
s3c_gpio_setpull(S5PV210_GPJ4(2), S3C_GPIO_PULL_NONE);
gpio_direction_output(S5PV210_GPJ4(2), 0);
gpio_free(S5PV210_GPJ4(2));
}
return 0;
}
static int sr130pc10_power_en_cam_B(int onoff)
{
int err;
/* Camera B */
if(onoff)
{
err = gpio_request(S5PV210_GPJ4(3), "GPJ4");
if (err)
printk(KERN_ERR "failed to request GPJ4 for CAM_2V8\n");
s3c_gpio_setpull(S5PV210_GPJ4(3), S3C_GPIO_PULL_NONE);
gpio_direction_output(S5PV210_GPJ4(3), 1);
gpio_free(S5PV210_GPJ4(3));
err = gpio_request(S5PV210_GPJ4(4), "GPJ4");
if (err)
printk(KERN_ERR "failed to request GPJ4 for CAM_2V8\n");
s3c_gpio_setpull(S5PV210_GPJ4(4), S3C_GPIO_PULL_NONE);
gpio_direction_output(S5PV210_GPJ4(4), 1);
gpio_free(S5PV210_GPJ4(4));
}
else
{
err = gpio_request(S5PV210_GPJ4(3), "GPJ4");
if (err)
printk(KERN_ERR "failed to request GPJ4 for CAM_2V8\n");
s3c_gpio_setpull(S5PV210_GPJ4(3), S3C_GPIO_PULL_NONE);
gpio_direction_output(S5PV210_GPJ4(3), 0);
gpio_free(S5PV210_GPJ4(3));
err = gpio_request(S5PV210_GPJ4(4), "GPJ4");
if (err)
printk(KERN_ERR "failed to request GPJ4 for CAM_2V8\n");
s3c_gpio_setpull(S5PV210_GPJ4(4), S3C_GPIO_PULL_NONE);
gpio_direction_output(S5PV210_GPJ4(4), 0);
gpio_free(S5PV210_GPJ4(4));
}
return 0;
}
#endif
#ifdef CONFIG_VIDEO_SR130PC10
static struct sr130pc10_platform_data sr130pc10_plat = {
.default_width = 640,
.default_height = 480,
.pixelformat = V4L2_PIX_FMT_YUYV,
.freq = 44000000,
.is_mipi = 0,
};
static struct i2c_board_info sr130pc10_i2c_info = {
I2C_BOARD_INFO("SR130PC10", 0x20),
.platform_data = &sr130pc10_plat,
};
static struct s3c_platform_camera sr130pc10_cam_a = {
.id = CAMERA_PAR_A,
.type = CAM_TYPE_ITU,
.fmt = ITU_601_YCBCR422_8BIT,
.order422 = CAM_ORDER422_8BIT_YCBYCR,
.i2c_busnum = 0,
.info = &sr130pc10_i2c_info,
.pixelformat = V4L2_PIX_FMT_YUYV,
//.srclk_name = "mout_mpll",
.srclk_name = "xusbxti",
.clk_name = "sclk_cam",
.clk_rate = 24000000,
.line_length = 1920,
.width = 640,
.height = 480,
.window = {
.left = 0,
.top = 0,
.width = 640,
.height = 480,
},
/* Polarity */
.inv_pclk = 0,
.inv_vsync = 1,
.inv_href = 0,
.inv_hsync = 0,
.initialized = 0,
.cam_power = sr130pc10_power_en_cam_A,
};
static struct s3c_platform_camera sr130pc10_cam_b = {
.id = CAMERA_PAR_B,
.type = CAM_TYPE_ITU,
.fmt = ITU_601_YCBCR422_8BIT,
.order422 = CAM_ORDER422_8BIT_YCBYCR,
.i2c_busnum = 1,
.info = &sr130pc10_i2c_info,
.pixelformat = V4L2_PIX_FMT_YUYV,
//.srclk_name = "mout_mpll",
.srclk_name = "xusbxti",
.clk_name = "sclk_cam",
.clk_rate = 24000000,
.line_length = 1920,
.width = 640,
.height = 480,
.window = {
.left = 0,
.top = 0,
.width = 640,
.height = 480,
},
/* Polarity */
.inv_pclk = 0,
.inv_vsync = 1,
.inv_href = 0,
.inv_hsync = 0,
.initialized = 0,
.cam_power = sr130pc10_power_en_cam_B,
};
#endif
static struct s3c_platform_fimc fimc_plat_lsi = {
.srclk_name = "mout_mpll",
.clk_name = "sclk_fimc",
.lclk_name = "sclk_fimc_lclk",
.clk_rate = 166750000,
.default_cam = CAMERA_PAR_A,
//.default_cam = CAMERA_PAR_B,
.camera = {
#ifdef CONFIG_VIDEO_MT9P111
&mt9p111,
#endif
#ifdef CONFIG_VIDEO_NOON130PC20
&noon130pc20,
#endif
//crazyboys
#ifdef CONFIG_VIDEO_SR130PC10
&sr130pc10_cam_a,
#endif
},
.hw_ver = 0x43,
};
수정을 합니다.
$ cd drivers/media/video/
[icanjji@icanjji-pc video]$ cp noon130pc20.c sr130pc10.c
[icanjji@icanjji-pc video]$ cp noon130pc20.h sr130pc10.h
$ vi sr130pc10.c
: %s/noon130pc20/sr130pc10/g
:%s/NOON130PC20/SR130PC10/g
$ vi sr130pc10.h
: %s/noon130pc20/sr130pc10/g
:%s/NOON130PC20/SR130PC10/g
위와 같이 변경을 합니다.
이제 초기화 값을 변경 해 보겠습니다.
에서
커널 소스에서
“driver/media/video/sr130pc10.h” 파일에서
static unsigned char sr130pc10_init_reg[][2] = {
초기화 값으로 대체합니다.
"drivers/media/video/Kconfig" 파일에서 아래와 같이 추가 합니다.
config VIDEO_SR130PC10
tristate "SR130PC10 Camera Sensor"
depends on I2C && VIDEO_V4L2
---help---
This driver supports CRZ sr130pc10 SoC camera module
“drivers/media/video/Makefile” 파일에서
obj-$(CONFIG_VIDEO_SR130PC10) += sr130pc10.o
추가
그리고, 커널 빌드를 합니다.
./build_kernel mango210_7inch_mrvl8787_5M_android_defconfig
빌드 후
[icanjji@icanjji-pc kernel]$ export ARCH=arm
[icanjji@icanjji-pc kernel]$ export CROSS_COMPILE=arm-none-linux-gnueabi-
[icanjji@icanjji-pc kernel]$ export PATH=$PATH:/opt/arm-2009q3/bin
[icanjji@icanjji-pc kernel]$ make menuconfig
scripts/kconfig/lxdialog/menubox.o: In function `print_buttons':
menubox.c:(.text+0x4d4): undefined reference to `wrefresh'
collect2: ld returned 1 exit status
make[1]: *** [scripts/kconfig/mconf] 오류 1
make: *** [menuconfig] 오류 2
오류 발생 시
[icanjji@icanjji-pc kernel]$ sudo apt-get install libncurses5-dev
설치 후
[icanjji@icanjji-pc kernel]$ make menuconfig
Device Drivers --->
<*> Multimedia support --->
[*] Video capture adapters --->
x x < > NOON130PC20 Camera Sensor x x
x x <*> SR130PC10 Camera Sensor x x
x x < > MT9P111 5M Camera Sensor
에서 SR130PC10 을 선택을 합니다.
$ ./build_kernel_only
drivers/media/video/sr130pc10.c:21: fatal error: media/sr130pc10_platform.h: No such file or directory
에러 발생 시
[icanjji@icanjji-pc kernel]$ find -name "noon*_platform.h"
./include/media/noon130pc20_platform.h
[icanjji@icanjji-pc kernel]$ cd ./include/media/
$ cp noon130pc20_platform.h sr130pc10_platform.h
$ vi sr130pc10_platform.h
: %s/noon130pc20/sr130pc10/g
:%s/NOON130PC20/SR130PC10/g
이름을 변경합니다.
[icanjji@icanjji-pc media]$ cd ../../
[icanjji@icanjji-pc kernel]$ ./build_kernel_only
다시 빌드합니다.
[sd 부팅 이미지 만드는 방법 ]
$df
[icanjji@icanjji-pc sdwriter]$ df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda2 1947374844 912226028 937686708 50% /
udev 2006136 4 2006132 1% /dev
tmpfs 805972 1388 804584 1% /run
none 5120 0 5120 0% /run/lock
none 2014924 76 2014848 1% /run/shm
/dev/sda1 96880 120 96760 1% /boot/efi
/dev/sdh2 231976 185676 46300 81% /media/57f8f4bc-abf4-655f-bf67-946fc0f9f25b
/dev/sdh1 7070048 60 7069988 1% /media/0000-3333
/dev/sdh4 103736 4152 94232 5% /media/01e933f7-9fc3-d2d1-3e9e-aa6a16374945
/dev/sdh3 348264 74320 255968 23% /media/bf92f2a0-24af-907b-fc47-68149b22cd30
$ cd sdwriter/
$ sudo ./sdwriter sdh 210
[ image write ]
SD boot image를 SD 0번 채널에 삽입한다.
전원을 인가하고, usb otg, RS232 연결
u-boot 실행 후
아무키나 누르고
mango210 보드 1, 3, 4 ON
CM-V210 보드 2, 3, 6 ON
MANGO210 # nand scrub
MANGO210 # fastboot
[Linux PC ]
$ cd image
$sudo ./fastboot flash bootloader u-boot.bin
부팅 스위치 변경
Mango210 : 1,2 ON
CM-V210 : 1, 6 ON
전원인가
u-boot 실행 후 아무키나 누르고,
MANGO210 # fastboot
Fastboot: employ default partition information
[Partition table on NAND]
ptn 0 name='bootloader' start=0x0 len=0x100000(~1024KB)
ptn 1 name='recovery' start=0x100000 len=0x500000(~5120KB)
ptn 2 name='kernel' start=0x600000 len=0x500000(~5120KB)
ptn 3 name='ramdisk' start=0xB00000 len=0x300000(~3072KB)
ptn 4 name='system' start=0xE00000 len=0x9800000(~155648KB) (Ubifs)
ptn 5 name='userdata' start=0xA600000 len=N/A (Ubifs)
[Linux PC ]
sudo ./fastboot -w flash kernel zImage
sudo ./fastboot flash ramdisk ramdisk-u-boot.img
sudo ./fastboot flash system system.img
sudo ./fastboot flash userdata userdata.img
후 카메라 부팅 후 카메라 부팅이 되면,
kernel에서
[icanjji@icanjji-pc kernel]$ cp .config mango210_7inch_sr130pc10_mrvl8787_defconfig
[icanjji@icanjji-pc kernel]$ cp mango210_7inch_sr130pc10_mrvl8787_defconfig arch/arm/configs/
해 둡니다.
이제 커널에서
$ ./build_kernel mango210_7inch_sr130pc10_mrvl8787_defconfig
하면 zImage가 만들어 집니다.
MANGO210 # print
mtdpart=80000 400000 3000000
bootdelay=0
baudrate=115200
ethaddr=00:40:5c:26:0a:5b
ipaddr=192.168.1.121
serverip=192.168.0.2
gatewayip=192.168.1.1
netmask=255.255.255.0
mtdids=nand0=s5pv210-nand
mtdparts=mtdparts=s5pv210-nand:1m(bootloader),5m(recovery),5m(kernel),3m(ramdisk),152m(system),90m(userdata)
bootcmd=nand read 20008000 600000 500000;nand read 21000000 B00000 300000;bootm 20008000 21000000
bootargs=root=ramfs devfs=mount console=ttySAC1,115200 ubi.mtd=4 ubi.mtd=5 ethaddr=00:40:5c:26:0a:5b
partition=nand0,0
mtddevnum=0
mtddevname=bootloader
Environment size: 556/16380 bytes
MANGO210 # boot