GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / dream / camera / msm_vfe8x.c
blobd87d56f914de832cd3e398abd84f707cd7795729
1 /*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4 #include <linux/slab.h>
5 #include <linux/uaccess.h>
6 #include <linux/interrupt.h>
7 #include <mach/irqs.h>
8 #include "msm_vfe8x_proc.h"
10 #define ON 1
11 #define OFF 0
13 struct mutex vfe_lock;
14 static void *vfe_syncdata;
16 static int vfe_enable(struct camera_enable_cmd *enable)
18 int rc = 0;
19 return rc;
22 static int vfe_disable(struct camera_enable_cmd *enable,
23 struct platform_device *dev)
25 int rc = 0;
27 vfe_stop();
29 msm_camio_disable(dev);
30 return rc;
33 static void vfe_release(struct platform_device *dev)
35 msm_camio_disable(dev);
36 vfe_cmd_release(dev);
38 mutex_lock(&vfe_lock);
39 vfe_syncdata = NULL;
40 mutex_unlock(&vfe_lock);
43 static void vfe_config_axi(int mode,
44 struct axidata *ad, struct vfe_cmd_axi_output_config *ao)
46 struct msm_pmem_region *regptr;
47 int i, j;
48 uint32_t *p1, *p2;
50 if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
51 regptr = ad->region;
52 for (i = 0;
53 i < ad->bufnum1; i++) {
55 p1 = &(ao->output1.outputY.outFragments[i][0]);
56 p2 = &(ao->output1.outputCbcr.outFragments[i][0]);
58 for (j = 0;
59 j < ao->output1.fragmentCount; j++) {
61 *p1 = regptr->paddr + regptr->y_off;
62 p1++;
64 *p2 = regptr->paddr + regptr->cbcr_off;
65 p2++;
67 regptr++;
69 } /* if OUTPUT1 or Both */
71 if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
73 regptr = &(ad->region[ad->bufnum1]);
74 CDBG("bufnum2 = %d\n", ad->bufnum2);
76 for (i = 0;
77 i < ad->bufnum2; i++) {
79 p1 = &(ao->output2.outputY.outFragments[i][0]);
80 p2 = &(ao->output2.outputCbcr.outFragments[i][0]);
82 CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, cbcr_off = %d\n",
83 regptr->paddr, regptr->y_off, regptr->cbcr_off);
85 for (j = 0;
86 j < ao->output2.fragmentCount; j++) {
88 *p1 = regptr->paddr + regptr->y_off;
89 CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
90 p1++;
92 *p2 = regptr->paddr + regptr->cbcr_off;
93 CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
94 p2++;
96 regptr++;
101 static int vfe_proc_general(struct msm_vfe_command_8k *cmd)
103 int rc = 0;
105 CDBG("vfe_proc_general: cmdID = %d\n", cmd->id);
107 switch (cmd->id) {
108 case VFE_CMD_ID_RESET:
109 msm_camio_vfe_blk_reset();
110 msm_camio_camif_pad_reg_reset_2();
111 vfe_reset();
112 break;
114 case VFE_CMD_ID_START: {
115 struct vfe_cmd_start start;
116 if (copy_from_user(&start,
117 (void __user *) cmd->value, cmd->length))
118 rc = -EFAULT;
120 /* msm_camio_camif_pad_reg_reset_2(); */
121 msm_camio_camif_pad_reg_reset();
122 vfe_start(&start);
124 break;
126 case VFE_CMD_ID_CAMIF_CONFIG: {
127 struct vfe_cmd_camif_config camif;
128 if (copy_from_user(&camif,
129 (void __user *) cmd->value, cmd->length))
130 rc = -EFAULT;
132 vfe_camif_config(&camif);
134 break;
136 case VFE_CMD_ID_BLACK_LEVEL_CONFIG: {
137 struct vfe_cmd_black_level_config bl;
138 if (copy_from_user(&bl,
139 (void __user *) cmd->value, cmd->length))
140 rc = -EFAULT;
142 vfe_black_level_config(&bl);
144 break;
146 case VFE_CMD_ID_ROLL_OFF_CONFIG: {
147 struct vfe_cmd_roll_off_config rolloff;
148 if (copy_from_user(&rolloff,
149 (void __user *) cmd->value, cmd->length))
150 rc = -EFAULT;
152 vfe_roll_off_config(&rolloff);
154 break;
156 case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG: {
157 struct vfe_cmd_demux_channel_gain_config demuxc;
158 if (copy_from_user(&demuxc,
159 (void __user *) cmd->value, cmd->length))
160 rc = -EFAULT;
162 /* demux is always enabled. */
163 vfe_demux_channel_gain_config(&demuxc);
165 break;
167 case VFE_CMD_ID_DEMOSAIC_CONFIG: {
168 struct vfe_cmd_demosaic_config demosaic;
169 if (copy_from_user(&demosaic,
170 (void __user *) cmd->value, cmd->length))
171 rc = -EFAULT;
173 vfe_demosaic_config(&demosaic);
175 break;
177 case VFE_CMD_ID_FOV_CROP_CONFIG:
178 case VFE_CMD_ID_FOV_CROP_UPDATE: {
179 struct vfe_cmd_fov_crop_config fov;
180 if (copy_from_user(&fov,
181 (void __user *) cmd->value, cmd->length))
182 rc = -EFAULT;
184 vfe_fov_crop_config(&fov);
186 break;
188 case VFE_CMD_ID_MAIN_SCALER_CONFIG:
189 case VFE_CMD_ID_MAIN_SCALER_UPDATE: {
190 struct vfe_cmd_main_scaler_config mainds;
191 if (copy_from_user(&mainds,
192 (void __user *) cmd->value, cmd->length))
193 rc = -EFAULT;
195 vfe_main_scaler_config(&mainds);
197 break;
199 case VFE_CMD_ID_WHITE_BALANCE_CONFIG:
200 case VFE_CMD_ID_WHITE_BALANCE_UPDATE: {
201 struct vfe_cmd_white_balance_config wb;
202 if (copy_from_user(&wb,
203 (void __user *) cmd->value, cmd->length))
204 rc = -EFAULT;
206 vfe_white_balance_config(&wb);
208 break;
210 case VFE_CMD_ID_COLOR_CORRECTION_CONFIG:
211 case VFE_CMD_ID_COLOR_CORRECTION_UPDATE: {
212 struct vfe_cmd_color_correction_config cc;
213 if (copy_from_user(&cc,
214 (void __user *) cmd->value, cmd->length))
215 rc = -EFAULT;
217 vfe_color_correction_config(&cc);
219 break;
221 case VFE_CMD_ID_LA_CONFIG: {
222 struct vfe_cmd_la_config la;
223 if (copy_from_user(&la,
224 (void __user *) cmd->value, cmd->length))
225 rc = -EFAULT;
227 vfe_la_config(&la);
229 break;
231 case VFE_CMD_ID_RGB_GAMMA_CONFIG: {
232 struct vfe_cmd_rgb_gamma_config rgb;
233 if (copy_from_user(&rgb,
234 (void __user *) cmd->value, cmd->length))
235 rc = -EFAULT;
237 rc = vfe_rgb_gamma_config(&rgb);
239 break;
241 case VFE_CMD_ID_CHROMA_ENHAN_CONFIG:
242 case VFE_CMD_ID_CHROMA_ENHAN_UPDATE: {
243 struct vfe_cmd_chroma_enhan_config chrom;
244 if (copy_from_user(&chrom,
245 (void __user *) cmd->value, cmd->length))
246 rc = -EFAULT;
248 vfe_chroma_enhan_config(&chrom);
250 break;
252 case VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG:
253 case VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE: {
254 struct vfe_cmd_chroma_suppression_config chromsup;
255 if (copy_from_user(&chromsup,
256 (void __user *) cmd->value, cmd->length))
257 rc = -EFAULT;
259 vfe_chroma_sup_config(&chromsup);
261 break;
263 case VFE_CMD_ID_ASF_CONFIG: {
264 struct vfe_cmd_asf_config asf;
265 if (copy_from_user(&asf,
266 (void __user *) cmd->value, cmd->length))
267 rc = -EFAULT;
269 vfe_asf_config(&asf);
271 break;
273 case VFE_CMD_ID_SCALER2Y_CONFIG:
274 case VFE_CMD_ID_SCALER2Y_UPDATE: {
275 struct vfe_cmd_scaler2_config ds2y;
276 if (copy_from_user(&ds2y,
277 (void __user *) cmd->value, cmd->length))
278 rc = -EFAULT;
280 vfe_scaler2y_config(&ds2y);
282 break;
284 case VFE_CMD_ID_SCALER2CbCr_CONFIG:
285 case VFE_CMD_ID_SCALER2CbCr_UPDATE: {
286 struct vfe_cmd_scaler2_config ds2cbcr;
287 if (copy_from_user(&ds2cbcr,
288 (void __user *) cmd->value, cmd->length))
289 rc = -EFAULT;
291 vfe_scaler2cbcr_config(&ds2cbcr);
293 break;
295 case VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG: {
296 struct vfe_cmd_chroma_subsample_config sub;
297 if (copy_from_user(&sub,
298 (void __user *) cmd->value, cmd->length))
299 rc = -EFAULT;
301 vfe_chroma_subsample_config(&sub);
303 break;
305 case VFE_CMD_ID_FRAME_SKIP_CONFIG: {
306 struct vfe_cmd_frame_skip_config fskip;
307 if (copy_from_user(&fskip,
308 (void __user *) cmd->value, cmd->length))
309 rc = -EFAULT;
311 vfe_frame_skip_config(&fskip);
313 break;
315 case VFE_CMD_ID_OUTPUT_CLAMP_CONFIG: {
316 struct vfe_cmd_output_clamp_config clamp;
317 if (copy_from_user(&clamp,
318 (void __user *) cmd->value, cmd->length))
319 rc = -EFAULT;
321 vfe_output_clamp_config(&clamp);
323 break;
325 /* module update commands */
326 case VFE_CMD_ID_BLACK_LEVEL_UPDATE: {
327 struct vfe_cmd_black_level_config blk;
328 if (copy_from_user(&blk,
329 (void __user *) cmd->value, cmd->length))
330 rc = -EFAULT;
332 vfe_black_level_update(&blk);
334 break;
336 case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE: {
337 struct vfe_cmd_demux_channel_gain_config dmu;
338 if (copy_from_user(&dmu,
339 (void __user *) cmd->value, cmd->length))
340 rc = -EFAULT;
342 vfe_demux_channel_gain_update(&dmu);
344 break;
346 case VFE_CMD_ID_DEMOSAIC_BPC_UPDATE: {
347 struct vfe_cmd_demosaic_bpc_update demo_bpc;
348 if (copy_from_user(&demo_bpc,
349 (void __user *) cmd->value, cmd->length))
350 rc = -EFAULT;
352 vfe_demosaic_bpc_update(&demo_bpc);
354 break;
356 case VFE_CMD_ID_DEMOSAIC_ABF_UPDATE: {
357 struct vfe_cmd_demosaic_abf_update demo_abf;
358 if (copy_from_user(&demo_abf,
359 (void __user *) cmd->value, cmd->length))
360 rc = -EFAULT;
362 vfe_demosaic_abf_update(&demo_abf);
364 break;
366 case VFE_CMD_ID_LA_UPDATE: {
367 struct vfe_cmd_la_config la;
368 if (copy_from_user(&la,
369 (void __user *) cmd->value, cmd->length))
370 rc = -EFAULT;
372 vfe_la_update(&la);
374 break;
376 case VFE_CMD_ID_RGB_GAMMA_UPDATE: {
377 struct vfe_cmd_rgb_gamma_config rgb;
378 if (copy_from_user(&rgb,
379 (void __user *) cmd->value, cmd->length))
380 rc = -EFAULT;
382 rc = vfe_rgb_gamma_update(&rgb);
384 break;
386 case VFE_CMD_ID_ASF_UPDATE: {
387 struct vfe_cmd_asf_update asf;
388 if (copy_from_user(&asf,
389 (void __user *) cmd->value, cmd->length))
390 rc = -EFAULT;
392 vfe_asf_update(&asf);
394 break;
396 case VFE_CMD_ID_FRAME_SKIP_UPDATE: {
397 struct vfe_cmd_frame_skip_update fskip;
398 if (copy_from_user(&fskip,
399 (void __user *) cmd->value, cmd->length))
400 rc = -EFAULT;
402 vfe_frame_skip_update(&fskip);
404 break;
406 case VFE_CMD_ID_CAMIF_FRAME_UPDATE: {
407 struct vfe_cmds_camif_frame fup;
408 if (copy_from_user(&fup,
409 (void __user *) cmd->value, cmd->length))
410 rc = -EFAULT;
412 vfe_camif_frame_update(&fup);
414 break;
416 /* stats update commands */
417 case VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE: {
418 struct vfe_cmd_stats_af_update afup;
419 if (copy_from_user(&afup,
420 (void __user *) cmd->value, cmd->length))
421 rc = -EFAULT;
423 vfe_stats_update_af(&afup);
425 break;
427 case VFE_CMD_ID_STATS_WB_EXP_UPDATE: {
428 struct vfe_cmd_stats_wb_exp_update wbexp;
429 if (copy_from_user(&wbexp,
430 (void __user *) cmd->value, cmd->length))
431 rc = -EFAULT;
433 vfe_stats_update_wb_exp(&wbexp);
435 break;
437 /* control of start, stop, update, etc... */
438 case VFE_CMD_ID_STOP:
439 vfe_stop();
440 break;
442 case VFE_CMD_ID_GET_HW_VERSION:
443 break;
445 /* stats */
446 case VFE_CMD_ID_STATS_SETTING: {
447 struct vfe_cmd_stats_setting stats;
448 if (copy_from_user(&stats,
449 (void __user *) cmd->value, cmd->length))
450 rc = -EFAULT;
452 vfe_stats_setting(&stats);
454 break;
456 case VFE_CMD_ID_STATS_AUTOFOCUS_START: {
457 struct vfe_cmd_stats_af_start af;
458 if (copy_from_user(&af,
459 (void __user *) cmd->value, cmd->length))
460 rc = -EFAULT;
462 vfe_stats_start_af(&af);
464 break;
466 case VFE_CMD_ID_STATS_AUTOFOCUS_STOP:
467 vfe_stats_af_stop();
468 break;
470 case VFE_CMD_ID_STATS_WB_EXP_START: {
471 struct vfe_cmd_stats_wb_exp_start awexp;
472 if (copy_from_user(&awexp,
473 (void __user *) cmd->value, cmd->length))
474 rc = -EFAULT;
476 vfe_stats_start_wb_exp(&awexp);
478 break;
480 case VFE_CMD_ID_STATS_WB_EXP_STOP:
481 vfe_stats_wb_exp_stop();
482 break;
484 case VFE_CMD_ID_ASYNC_TIMER_SETTING:
485 break;
487 case VFE_CMD_ID_UPDATE:
488 vfe_update();
489 break;
491 /* test gen */
492 case VFE_CMD_ID_TEST_GEN_START:
493 break;
496 acknowledge from upper layer
497 these are not in general command.
499 case VFE_CMD_ID_OUTPUT1_ACK:
500 break;
501 case VFE_CMD_ID_OUTPUT2_ACK:
502 break;
503 case VFE_CMD_ID_EPOCH1_ACK:
504 break;
505 case VFE_CMD_ID_EPOCH2_ACK:
506 break;
507 case VFE_CMD_ID_STATS_AUTOFOCUS_ACK:
508 break;
509 case VFE_CMD_ID_STATS_WB_EXP_ACK:
510 break;
513 default:
514 break;
515 } /* switch */
517 return rc;
520 static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
522 struct msm_pmem_region *regptr;
523 struct msm_vfe_command_8k vfecmd;
525 uint32_t i;
527 void *cmd_data = NULL;
528 long rc = 0;
530 struct vfe_cmd_axi_output_config *axio = NULL;
531 struct vfe_cmd_stats_setting *scfg = NULL;
533 if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
534 cmd->cmd_type != CMD_STATS_BUF_RELEASE) {
536 if (copy_from_user(&vfecmd,
537 (void __user *)(cmd->value),
538 sizeof(struct msm_vfe_command_8k)))
539 return -EFAULT;
542 CDBG("vfe_config: cmdType = %d\n", cmd->cmd_type);
544 switch (cmd->cmd_type) {
545 case CMD_GENERAL:
546 rc = vfe_proc_general(&vfecmd);
547 break;
549 case CMD_STATS_ENABLE:
550 case CMD_STATS_AXI_CFG: {
551 struct axidata *axid;
553 axid = data;
554 if (!axid)
555 return -EFAULT;
557 scfg =
558 kmalloc(sizeof(struct vfe_cmd_stats_setting),
559 GFP_ATOMIC);
560 if (!scfg)
561 return -ENOMEM;
563 if (copy_from_user(scfg,
564 (void __user *)(vfecmd.value),
565 vfecmd.length)) {
567 kfree(scfg);
568 return -EFAULT;
571 regptr = axid->region;
572 if (axid->bufnum1 > 0) {
573 for (i = 0; i < axid->bufnum1; i++) {
574 scfg->awbBuffer[i] =
575 (uint32_t)(regptr->paddr);
576 regptr++;
580 if (axid->bufnum2 > 0) {
581 for (i = 0; i < axid->bufnum2; i++) {
582 scfg->afBuffer[i] =
583 (uint32_t)(regptr->paddr);
584 regptr++;
588 vfe_stats_config(scfg);
590 break;
592 case CMD_STATS_AF_AXI_CFG: {
594 break;
596 case CMD_FRAME_BUF_RELEASE: {
597 /* preview buffer release */
598 struct msm_frame *b;
599 unsigned long p;
600 struct vfe_cmd_output_ack fack;
602 if (!data)
603 return -EFAULT;
605 b = (struct msm_frame *)(cmd->value);
606 p = *(unsigned long *)data;
608 b->path = MSM_FRAME_ENC;
610 fack.ybufaddr[0] =
611 (uint32_t)(p + b->y_off);
613 fack.chromabufaddr[0] =
614 (uint32_t)(p + b->cbcr_off);
616 if (b->path == MSM_FRAME_PREV_1)
617 vfe_output1_ack(&fack);
619 if (b->path == MSM_FRAME_ENC ||
620 b->path == MSM_FRAME_PREV_2)
621 vfe_output2_ack(&fack);
623 break;
625 case CMD_SNAP_BUF_RELEASE: {
627 break;
629 case CMD_STATS_BUF_RELEASE: {
630 struct vfe_cmd_stats_wb_exp_ack sack;
632 if (!data)
633 return -EFAULT;
635 sack.nextWbExpOutputBufferAddr = *(uint32_t *)data;
636 vfe_stats_wb_exp_ack(&sack);
638 break;
640 case CMD_AXI_CFG_OUT1: {
641 struct axidata *axid;
643 axid = data;
644 if (!axid)
645 return -EFAULT;
647 axio = memdup_user((void __user *)(vfecmd.value),
648 sizeof(struct vfe_cmd_axi_output_config));
649 if (IS_ERR(axio))
650 return PTR_ERR(axio);
652 vfe_config_axi(OUTPUT_1, axid, axio);
653 vfe_axi_output_config(axio);
655 break;
657 case CMD_AXI_CFG_OUT2:
658 case CMD_RAW_PICT_AXI_CFG: {
659 struct axidata *axid;
661 axid = data;
662 if (!axid)
663 return -EFAULT;
665 axio = memdup_user((void __user *)(vfecmd.value),
666 sizeof(struct vfe_cmd_axi_output_config));
667 if (IS_ERR(axio))
668 return PTR_ERR(axio);
670 vfe_config_axi(OUTPUT_2, axid, axio);
672 axio->outputDataSize = 0;
673 vfe_axi_output_config(axio);
675 break;
677 case CMD_AXI_CFG_SNAP_O1_AND_O2: {
678 struct axidata *axid;
679 axid = data;
680 if (!axid)
681 return -EFAULT;
683 axio = memdup_user((void __user *)(vfecmd.value),
684 sizeof(struct vfe_cmd_axi_output_config));
685 if (IS_ERR(axio))
686 return PTR_ERR(axio);
688 vfe_config_axi(OUTPUT_1_AND_2,
689 axid, axio);
690 vfe_axi_output_config(axio);
691 cmd_data = axio;
693 break;
695 default:
696 break;
697 } /* switch */
699 kfree(scfg);
701 kfree(axio);
704 if (cmd->length > 256 &&
705 cmd_data &&
706 (cmd->cmd_type == CMD_GENERAL ||
707 cmd->cmd_type == CMD_STATS_DISABLE)) {
708 kfree(cmd_data);
711 return rc;
714 static int vfe_init(struct msm_vfe_callback *presp,
715 struct platform_device *dev)
717 int rc = 0;
719 rc = vfe_cmd_init(presp, dev, vfe_syncdata);
720 if (rc < 0)
721 return rc;
723 /* Bring up all the required GPIOs and Clocks */
724 return msm_camio_enable(dev);
727 void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
729 mutex_init(&vfe_lock);
730 fptr->vfe_init = vfe_init;
731 fptr->vfe_enable = vfe_enable;
732 fptr->vfe_config = vfe_config;
733 fptr->vfe_disable = vfe_disable;
734 fptr->vfe_release = vfe_release;
735 vfe_syncdata = data;