⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3xa_sensor.c

📁 ADV7180 linux驱动源代码。基于三星S3C6410的ADV7180 linux驱动程序。ARM。
💻 C
字号:
  1 /*
  2  *  Copyright (C) 2004 Samsung Electronics 
  3  *             SW.LEE <hitchcar@samsung.com>
  4  *            - based on Russell King : pcf8583.c
  5  *            - added  smdk24a0, smdk2440
  6  *            - added  poseidon (s3c24a0+wavecom)       
  7  *
  8  * This program is free software; you can redistribute it and/or modify
  9  * it under the terms of the GNU General Public License version 2 as
 10  * published by the Free Software Foundation.
 11  *
 12  *  Driver for FIMC2.x Camera Decoder 
 13  *
 14  */
 15 
 16 //#include <linux/config.h>
 17 #include <linux/module.h>
 18 #include <linux/kernel.h>
 19 #include <linux/init.h>
 20 #include <linux/i2c.h>
 21 #include <linux/i2c-id.h>
 22 #include <linux/slab.h>
 23 #include <linux/string.h>
 24 #include <linux/init.h>
 25 #include <linux/delay.h>
 26 
 27 //#define CAMIF_DEBUG
 28 
 29 //#include <asm/arch/registers.h>
 30 #include "../s3c_camif.h"
 31 #include "3xa_sensor.h"
 32 
 33 static const char *sensor_version =
 34     "$Id: 3xa_sensor.c,v 1.3 2007/09/07 01:11:37 yreom Exp $";
 35 
 36 
 37 static struct i2c_driver sensor_driver;
 38 
 39 /* This is an abstract CIS sensor for MSDMA input. */
 40 
 41 camif_cis_t msdma_input = {
 42         itu_fmt:       CAMIF_ITU601,
 43         order422:      CAMIF_YCBYCR,            /* YCRYCB */
 44         camclk:        32000000,                /* No effect */
 45         source_x:      800,       
 46         source_y:      480,
 47         win_hor_ofst:  0,
 48         win_ver_ofst:  0,
 49         win_hor_ofst2: 0,
 50         win_ver_ofst2: 0,
 51         polarity_pclk: 0,
 52         polarity_vsync:1,
 53         polarity_href: 0,
 54         reset_type:CAMIF_EX_RESET_AH, /* Ref board has inverted signal */
 55         reset_udelay: 20000,
 56 };
 57 
 58 camif_cis_t interlace_input = {
 59         itu_fmt:       CAMIF_ITU601,
 60         order422:      CAMIF_YCBYCR,            /* YCRYCB */
 61         camclk:        32000000,                /* No effect */
 62         source_x:      720,       
 63         source_y:      243,
 64         win_hor_ofst:  0,
 65         win_ver_ofst:  0,
 66         win_hor_ofst2: 0,
 67         win_ver_ofst2: 0,
 68         polarity_pclk: 1,
 69         polarity_vsync:0,
 70         polarity_href: 0,
 71         reset_type:CAMIF_EX_RESET_AH, /* Ref board has inverted signal */
 72         reset_udelay: 20000,
 73 };
 74 
 75 #if defined(CONFIG_VIDEO_SAMSUNG_S5K3AA)
 76 /* This is SXGA(1280x1024) camera but start from VGA(640x480) mode */
 77 static camif_cis_t data = {
 78         itu_fmt:       CAMIF_ITU601,
 79         order422:      CAMIF_CBYCRY,             /* YCRYCB */
 80         camclk:        32000000,                 /* No effect */
 81         source_x:      640,
 82         source_y:      480,
 83         win_hor_ofst:  112,
 84         win_ver_ofst:  20,
 85         win_hor_ofst2: 112,
 86         win_ver_ofst2: 20,
 87         polarity_pclk: 1,
 88         polarity_vsync:0,
 89         polarity_href: 0,
 90         
 91 #ifdef CONFIG_CPU_S3C24A0A
 92         reset_type:CAMIF_EX_RESET_AL,           /* Active Low */
 93 #else
 94         reset_type:CAMIF_EX_RESET_AH,           /* Ref board has inverted signal */
 95 #endif
 96         reset_udelay: 20000,
 97 };
 98 
 99 s5k3xa_t s5k3aa_regs_mirror[S5K3AA_REGS];
100 
101 #elif defined(CONFIG_VIDEO_SAMSUNG_S5K3BA)
102 /* This is UXGA(1600x1200) camera but start from SVGA(800x600) mode */
103 static camif_cis_t data = {
104         itu_fmt:       CAMIF_ITU601,
105         order422:      CAMIF_YCBYCR,            /* YCRYCB */
106         camclk:        32000000,                /* No effect */
107         source_x:      640,       
108         source_y:      480,
109         win_hor_ofst:  112,
110         win_ver_ofst:  20,
111         win_hor_ofst2: 112,
112         win_ver_ofst2: 20,
113         polarity_pclk: 1,
114         polarity_vsync:1,
115         polarity_href: 0,
116         reset_type:CAMIF_EX_RESET_AH,           /* Ref board has inverted signal */
117         reset_udelay: 20000,
118 };
119 
120 s5k3xa_t s5k3ba_regs_mirror[S5K3BA_REGS];
121 #else
122 #error No samsung CIS moudule here !
123 #endif
124 
125 extern camif_cis_t* get_initialized_cis();
126 camif_cis_t* get_initialized_cis() {
127         if(data.init_sensor == 0) return NULL;
128         return &data;
129 
130 }
131 
132 #define CAM_ID 0x5a
133 
134 static unsigned short ignore[] = { I2C_CLIENT_END };
135 static unsigned short normal_addr[] = { (CAM_ID >> 1), I2C_CLIENT_END };
136 static unsigned short *forces[] = { NULL };
137 
138 static struct i2c_client_address_data addr_data = {
139       normal_i2c:normal_addr,
140       //normal_i2c_range:ignore,
141       probe:ignore,
142       //probe_range:ignore,
143       ignore:ignore,
144       //ignore_range:ignore,
145       forces:forces,
146 };
147 
148 
149 unsigned char sensor_read(struct i2c_client *client, unsigned char subaddr)
150 {
151         int ret;
152         unsigned char buf[1];
153         struct i2c_msg msg = { client->addr, 0, 1, buf };
154         buf[0] = subaddr;
155 
156         ret = i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
157         if (ret == -EIO) {
158                 printk(" I2C write Error \n");
159                 return -EIO;
160         }
161 
162         msg.flags = I2C_M_RD;
163         ret = i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
164 
165         return buf[0];
166 }
167 
168 
169 static int
170 sensor_write(struct i2c_client *client,
171              unsigned char subaddr, unsigned char val)
172 {
173         unsigned char buf[2];
174         struct i2c_msg msg = { client->addr, 0, 2, buf };
175 
176         buf[0] = subaddr;
177         buf[1] = val;
178 
179         return i2c_transfer(client->adapter, &msg, 1) == 1 ? 0 : -EIO;
180 }
181 
182 #if defined(CONFIG_VIDEO_SAMSUNG_S5K3AA)
183 void inline sensor_init(struct i2c_client *sam_client)
184 {
185         int i;
186         i = (sizeof(s5k3aa_reg)/sizeof(s5k3aa_reg[0]));
187 
188         for (i = 0; i < S5K3AA_INIT_REGS; i++) {
189                 sensor_write(sam_client,
190                              s5k3aa_reg[i].subaddr, s5k3aa_reg[i].value);
191 #if 0
192                         printk(KERN_ERR "Page:[%03d] Subaddr %02x = 0x%02x\n",i,
193                                s5k3aa_reg[i].subaddr,
194                                s5k3aa_reg[i].value);
195 #endif
196         }
197 
198 #ifdef YOU_WANT_TO_CHECK_IMG_SENSOR
199         for (i = 0; i < S5K3AA_INIT_REGS; i++) {
200                 if (s5k3aa_reg[i].subaddr == PAGE_ADDRESS) {
201                         sensor_write(sam_client,
202                                      s5k3aa_reg[i].subaddr,
203                                      s5k3aa_reg[i].value);
204 
205                         printk(KERN_ERR "Page: Subaddr %02x = 0x%02x\n",
206                                s5k3aa_reg[i].subaddr,
207                                s5k3aa_reg[i].value);
208 
209 
210                 } else {
211                         s5k3aa_regs_mirror[i].subaddr =
212                             s5k3aa_reg[i].subaddr;
213                         s5k3aa_regs_mirror[i].value =
214                             s5k3aa_read(sam_client, s5k3aa_reg[i].subaddr);
215                         printk(KERN_ERR "Subaddr %02x = 0x%02x\n",
216                                s5k3aa_reg[i].subaddr,
217                                s5k3aa_regs_mirror[i].value);
218                 }
219         }
220 #endif
221 }
222 
223 #elif defined(CONFIG_VIDEO_SAMSUNG_S5K3BA)
224 void inline sensor_init(struct i2c_client *sam_client)
225 {
226         int i;
227         i = (sizeof(s5k3ba_reg)/sizeof(s5k3ba_reg[0]));
228 
229         for (i = 0; i < S5K3BA_INIT_REGS; i++) { 
230                 sensor_write(sam_client,
231                              s5k3ba_reg[i].subaddr, s5k3ba_reg[i].value);
232         }
233 }
234 #else
235 #error No samsung CIS moudule !
236 #endif
237 
238 static int
239 s5k3xa_attach(struct i2c_adapter *adap, int addr, unsigned short flags,
240               int kind)
241 {
242         struct i2c_client *c;
243 
244         c = kmalloc(sizeof(*c), GFP_KERNEL);
245         if (!c)
246                 return -ENOMEM;
247 
248         memset(c, 0, sizeof(struct i2c_client));            
249 
250         strcpy(c->name, "S5K3XA");
251         //c->id = sensor_driver.id;
252         //c->flags = I2C_CLIENT_ALLOW_USE;
253         c->addr = addr;
254         c->adapter = adap;
255         c->driver = &sensor_driver;
256         c->data = &data;
257         data.sensor = c;
258 
259         camif_register_cis(c);
260         return i2c_attach_client(c);
261 }
262 
263 static int sensor_attach_adapter(struct i2c_adapter *adap)
264 {
265         return i2c_probe(adap, &addr_data, s5k3xa_attach);
266 }
267 
268 static int sensor_detach(struct i2c_client *client)
269 {
270         i2c_detach_client(client);
271         camif_unregister_cis(client);
272         return 0;
273 }
274 
275 /* Purpose:
276     This fucntion only for SXGA Camera : 3AA
277     This fucntion only for UXGA Camera : 3BA
278 */
279 static int change_sensor_size(struct i2c_client *client, int size)
280 {
281         int i;
282 
283         switch (size) {
284 #if defined(CONFIG_VIDEO_SAMSUNG_S5K3AA)
285         case SENSOR_VGA:
286                 for (i = 0; i < S5K3AA_VGA_REGS; i++) {
287                         sensor_write(client, s5k3aa_reg_vga[i].subaddr,
288                                      s5k3aa_reg_vga[i].value);
289                 }
290                 break;
291         case SENSOR_SXGA:
292                 for (i = 0; i < S5K3AA_SXGA_REGS; i++) {
293                         sensor_write(client, s5k3aa_reg_sxga[i].subaddr,
294                                      s5k3aa_reg_sxga[i].value);
295                 }
296                 break;
297                 
298 #elif defined(CONFIG_VIDEO_SAMSUNG_S5K3BA)
299         case SENSOR_VGA:
300                 for (i = 0; i < S5K3BA_VGA_REGS; i++) {
301                         sensor_write(client, s5k3ba_reg_vga[i].subaddr,
302                                      s5k3ba_reg_vga[i].value);
303                 }
304                 break;
305 
306         case SENSOR_SVGA:
307                 for (i = 0; i < S5K3BA_INIT_REGS; i++) {
308                         sensor_write(client, s5k3ba_reg[i].subaddr,
309                                      s5k3ba_reg[i].value);
310                 }
311                 break;
312         case SENSOR_UXGA:
313                 for (i = 0; i < S5K3BA_UXGA_REGS; i++) {
314                         sensor_write(client, s5k3ba_reg_uxga[i].subaddr,
315                                      s5k3ba_reg_uxga[i].value);
316                 }
317                 break;
318 #else
319 #error No samsung CIS moudule !
320 #endif
321         default:
322                 panic("3xa_sensor.c: unexpect value \n");
323         }
324 
325         return 0;
326 }
327 
328 static int change_sensor_wb(struct i2c_client *client, int type)
329 {
330        printk("[ *** Page 0, 3XA Sensor White Balance Mode ***]\n");
331        
332 #if defined(CONFIG_VIDEO_SAMSUNG_S5K3AA)
333        sensor_write(client, 0xEC, 0x0);
334        sensor_write(client, 0x30, type);
335 #elif defined(CONFIG_VIDEO_SAMSUNG_S5K3BA)
336        sensor_write(client, 0xFC, 0x0);
337        sensor_write(client, 0x30, type);
338 #endif
339        
340        switch(type){
341            case 0:
342            default:
343                 printk(" -> AWB auto mode ]\n");
344                 break;
345            case 1:
346                 printk(" -> Indoor 3100 mode ]\n");
347                 break;
348            case 2:
349                 printk(" -> Outdoor 5100 mode ]\n");
350                 break;
351            case 3:
352                 printk(" -> Indoor 2000 mode ]\n");
353                 break;
354            case 4:
355                 printk(" -> AE/AWB halt ]\n");
356                 break;
357            case 5:
358                 printk(" -> Cloudy(6000) mode ]\n");
359                 break;
360            case 6:
361                 printk(" -> Sunny(8000) mode ]\n");
362                 break;
363        }
364 
365        return 0;
366 }
367 
368 static int
369 sensor_command(struct i2c_client *client, unsigned int cmd, void *arg)
370 {
371         switch (cmd) {
372         case SENSOR_INIT:
373                 sensor_init(client);
374                 printk(KERN_INFO "External Camera initialized\n");
375                 break;
376                 
377         case USER_ADD:
378                 //MOD_INC_USE_COUNT;
379                 break;
380                 
381         case USER_EXIT:
382                 //MOD_DEC_USE_COUNT;
383                 break;
384                 
385         case SENSOR_VGA:
386                 change_sensor_size(client, SENSOR_VGA);
387                 break;
388                 
389         case SENSOR_SVGA:
390                 change_sensor_size(client, SENSOR_SVGA);
391                 break;
392                 
393         case SENSOR_SXGA:
394                 change_sensor_size(client, SENSOR_SXGA);
395                 break;
396                 
397         case SENSOR_UXGA:
398                 change_sensor_size(client, SENSOR_UXGA);
399                 break;
400 /* Todo
401         case SENSOR_BRIGHTNESS:
402                 change_sensor_setting();
403                 break;
404 */
405         case SENSOR_WB:
406                 printk("[ *** 3XA Sensor White Balance , No mode ***]\n");
407                 change_sensor_wb(client, arg);
408                 break;
409         
410         default:
411                 panic("3xa_sensor.c : Unexpect Sensor Command \n");
412                 break;
413         }
414         
415         return 0;
416 }
417 
418 static struct i2c_driver sensor_driver = {
419         .driver = {
420                 .name = "s5k3xa",
421         },
422       //name:"S5K3XA",
423       .id = I2C_DRIVERID_S5K_3XA,
424       //flags:I2C_DF_NOTIFY,
425       .attach_adapter = sensor_attach_adapter,
426       .detach_client = sensor_detach,
427       .command = sensor_command
428 };
429 
430 static __init int camif_sensor_init(void)
431 {
432         return i2c_add_driver(&sensor_driver);
433 }
434 
435 
436 static __init void camif_sensor_exit(void)
437 {
438         i2c_del_driver(&sensor_driver);
439 }
440 
441 module_init(camif_sensor_init)
442 module_exit(camif_sensor_exit)
443 
444 MODULE_AUTHOR("Yeom, Youngran <yeom@samsung.com>");
445 MODULE_DESCRIPTION("I2C Client Driver For Fimc3.x V4L2 Driver");
446 MODULE_LICENSE("GPL");
447 
448 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -