• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/staging/dream/camera/
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"
9
10#define ON  1
11#define OFF 0
12
13struct mutex vfe_lock;
14static void     *vfe_syncdata;
15
16static int vfe_enable(struct camera_enable_cmd *enable)
17{
18	int rc = 0;
19	return rc;
20}
21
22static int vfe_disable(struct camera_enable_cmd *enable,
23	struct platform_device *dev)
24{
25	int rc = 0;
26
27	vfe_stop();
28
29	msm_camio_disable(dev);
30	return rc;
31}
32
33static void vfe_release(struct platform_device *dev)
34{
35	msm_camio_disable(dev);
36	vfe_cmd_release(dev);
37
38	mutex_lock(&vfe_lock);
39	vfe_syncdata = NULL;
40	mutex_unlock(&vfe_lock);
41}
42
43static void vfe_config_axi(int mode,
44	struct axidata *ad, struct vfe_cmd_axi_output_config *ao)
45{
46	struct msm_pmem_region *regptr;
47	int i, j;
48	uint32_t *p1, *p2;
49
50	if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
51		regptr = ad->region;
52		for (i = 0;
53			i < ad->bufnum1; i++) {
54
55			p1 = &(ao->output1.outputY.outFragments[i][0]);
56			p2 = &(ao->output1.outputCbcr.outFragments[i][0]);
57
58			for (j = 0;
59				j < ao->output1.fragmentCount; j++) {
60
61				*p1 = regptr->paddr + regptr->y_off;
62				p1++;
63
64				*p2 = regptr->paddr + regptr->cbcr_off;
65				p2++;
66			}
67			regptr++;
68		}
69	} /* if OUTPUT1 or Both */
70
71	if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
72
73		regptr = &(ad->region[ad->bufnum1]);
74		CDBG("bufnum2 = %d\n", ad->bufnum2);
75
76		for (i = 0;
77			i < ad->bufnum2; i++) {
78
79			p1 = &(ao->output2.outputY.outFragments[i][0]);
80			p2 = &(ao->output2.outputCbcr.outFragments[i][0]);
81
82		CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, cbcr_off = %d\n",
83			regptr->paddr, regptr->y_off, regptr->cbcr_off);
84
85			for (j = 0;
86				j < ao->output2.fragmentCount; j++) {
87
88				*p1 = regptr->paddr + regptr->y_off;
89				CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
90				p1++;
91
92				*p2 = regptr->paddr + regptr->cbcr_off;
93				CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
94				p2++;
95			}
96			regptr++;
97		}
98	}
99}
100
101static int vfe_proc_general(struct msm_vfe_command_8k *cmd)
102{
103	int rc = 0;
104
105	CDBG("vfe_proc_general: cmdID = %d\n", cmd->id);
106
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;
113
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;
119
120		/* msm_camio_camif_pad_reg_reset_2(); */
121		msm_camio_camif_pad_reg_reset();
122		vfe_start(&start);
123	}
124		break;
125
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;
131
132		vfe_camif_config(&camif);
133	}
134		break;
135
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;
141
142		vfe_black_level_config(&bl);
143	}
144		break;
145
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;
151
152		vfe_roll_off_config(&rolloff);
153	}
154		break;
155
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;
161
162		/* demux is always enabled.  */
163		vfe_demux_channel_gain_config(&demuxc);
164	}
165		break;
166
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;
172
173		vfe_demosaic_config(&demosaic);
174	}
175		break;
176
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;
183
184		vfe_fov_crop_config(&fov);
185	}
186		break;
187
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;
194
195		vfe_main_scaler_config(&mainds);
196	}
197		break;
198
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;
205
206		vfe_white_balance_config(&wb);
207	}
208		break;
209
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;
216
217		vfe_color_correction_config(&cc);
218	}
219		break;
220
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;
226
227		vfe_la_config(&la);
228	}
229		break;
230
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;
236
237		rc = vfe_rgb_gamma_config(&rgb);
238	}
239		break;
240
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;
247
248		vfe_chroma_enhan_config(&chrom);
249	}
250		break;
251
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;
258
259		vfe_chroma_sup_config(&chromsup);
260	}
261		break;
262
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;
268
269		vfe_asf_config(&asf);
270	}
271		break;
272
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;
279
280		vfe_scaler2y_config(&ds2y);
281	}
282		break;
283
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;
290
291		vfe_scaler2cbcr_config(&ds2cbcr);
292	}
293		break;
294
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;
300
301		vfe_chroma_subsample_config(&sub);
302	}
303		break;
304
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;
310
311		vfe_frame_skip_config(&fskip);
312	}
313		break;
314
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;
320
321		vfe_output_clamp_config(&clamp);
322	}
323		break;
324
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;
331
332		vfe_black_level_update(&blk);
333	}
334		break;
335
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;
341
342		vfe_demux_channel_gain_update(&dmu);
343	}
344		break;
345
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;
351
352		vfe_demosaic_bpc_update(&demo_bpc);
353	}
354		break;
355
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;
361
362		vfe_demosaic_abf_update(&demo_abf);
363	}
364		break;
365
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;
371
372		vfe_la_update(&la);
373	}
374		break;
375
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;
381
382		rc = vfe_rgb_gamma_update(&rgb);
383	}
384		break;
385
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;
391
392		vfe_asf_update(&asf);
393	}
394		break;
395
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;
401
402		vfe_frame_skip_update(&fskip);
403	}
404		break;
405
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;
411
412		vfe_camif_frame_update(&fup);
413	}
414		break;
415
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;
422
423		vfe_stats_update_af(&afup);
424	}
425		break;
426
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;
432
433		vfe_stats_update_wb_exp(&wbexp);
434	}
435		break;
436
437	/* control of start, stop, update, etc... */
438	case VFE_CMD_ID_STOP:
439		vfe_stop();
440		break;
441
442	case VFE_CMD_ID_GET_HW_VERSION:
443		break;
444
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;
451
452		vfe_stats_setting(&stats);
453	}
454		break;
455
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;
461
462		vfe_stats_start_af(&af);
463	}
464		break;
465
466	case VFE_CMD_ID_STATS_AUTOFOCUS_STOP:
467		vfe_stats_af_stop();
468		break;
469
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;
475
476		vfe_stats_start_wb_exp(&awexp);
477	}
478		break;
479
480	case VFE_CMD_ID_STATS_WB_EXP_STOP:
481		vfe_stats_wb_exp_stop();
482		break;
483
484	case VFE_CMD_ID_ASYNC_TIMER_SETTING:
485		break;
486
487	case VFE_CMD_ID_UPDATE:
488		vfe_update();
489		break;
490
491	/* test gen */
492	case VFE_CMD_ID_TEST_GEN_START:
493		break;
494
495/*
496  acknowledge from upper layer
497	these are not in general command.
498
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;
511*/
512
513	default:
514		break;
515	} /* switch */
516
517	return rc;
518}
519
520static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
521{
522	struct msm_pmem_region *regptr;
523	struct msm_vfe_command_8k vfecmd;
524
525	uint32_t i;
526
527	void *cmd_data = NULL;
528	long rc = 0;
529
530	struct vfe_cmd_axi_output_config *axio = NULL;
531	struct vfe_cmd_stats_setting *scfg = NULL;
532
533	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
534	    cmd->cmd_type != CMD_STATS_BUF_RELEASE) {
535
536		if (copy_from_user(&vfecmd,
537				(void __user *)(cmd->value),
538				sizeof(struct msm_vfe_command_8k)))
539			return -EFAULT;
540	}
541
542	CDBG("vfe_config: cmdType = %d\n", cmd->cmd_type);
543
544	switch (cmd->cmd_type) {
545	case CMD_GENERAL:
546		rc = vfe_proc_general(&vfecmd);
547		break;
548
549	case CMD_STATS_ENABLE:
550	case CMD_STATS_AXI_CFG: {
551		struct axidata *axid;
552
553		axid = data;
554		if (!axid)
555			return -EFAULT;
556
557		scfg =
558			kmalloc(sizeof(struct vfe_cmd_stats_setting),
559				GFP_ATOMIC);
560		if (!scfg)
561			return -ENOMEM;
562
563		if (copy_from_user(scfg,
564					(void __user *)(vfecmd.value),
565					vfecmd.length)) {
566
567			kfree(scfg);
568			return -EFAULT;
569		}
570
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++;
577			}
578		}
579
580		if (axid->bufnum2 > 0) {
581			for (i = 0; i < axid->bufnum2; i++) {
582				scfg->afBuffer[i] =
583					(uint32_t)(regptr->paddr);
584				regptr++;
585			}
586		}
587
588		vfe_stats_config(scfg);
589	}
590		break;
591
592	case CMD_STATS_AF_AXI_CFG: {
593	}
594		break;
595
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;
601
602		if (!data)
603			return -EFAULT;
604
605		b = (struct msm_frame *)(cmd->value);
606		p = *(unsigned long *)data;
607
608		b->path = MSM_FRAME_ENC;
609
610		fack.ybufaddr[0] =
611			(uint32_t)(p + b->y_off);
612
613		fack.chromabufaddr[0] =
614			(uint32_t)(p + b->cbcr_off);
615
616		if (b->path == MSM_FRAME_PREV_1)
617			vfe_output1_ack(&fack);
618
619		if (b->path == MSM_FRAME_ENC ||
620		    b->path == MSM_FRAME_PREV_2)
621			vfe_output2_ack(&fack);
622	}
623		break;
624
625	case CMD_SNAP_BUF_RELEASE: {
626	}
627		break;
628
629	case CMD_STATS_BUF_RELEASE: {
630		struct vfe_cmd_stats_wb_exp_ack sack;
631
632		if (!data)
633			return -EFAULT;
634
635		sack.nextWbExpOutputBufferAddr = *(uint32_t *)data;
636		vfe_stats_wb_exp_ack(&sack);
637	}
638		break;
639
640	case CMD_AXI_CFG_OUT1: {
641		struct axidata *axid;
642
643		axid = data;
644		if (!axid)
645			return -EFAULT;
646
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);
651
652		vfe_config_axi(OUTPUT_1, axid, axio);
653		vfe_axi_output_config(axio);
654	}
655		break;
656
657	case CMD_AXI_CFG_OUT2:
658	case CMD_RAW_PICT_AXI_CFG: {
659		struct axidata *axid;
660
661		axid = data;
662		if (!axid)
663			return -EFAULT;
664
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);
669
670		vfe_config_axi(OUTPUT_2, axid, axio);
671
672		axio->outputDataSize = 0;
673		vfe_axi_output_config(axio);
674	}
675		break;
676
677	case CMD_AXI_CFG_SNAP_O1_AND_O2: {
678		struct axidata *axid;
679		axid = data;
680		if (!axid)
681			return -EFAULT;
682
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);
687
688		vfe_config_axi(OUTPUT_1_AND_2,
689			axid, axio);
690		vfe_axi_output_config(axio);
691		cmd_data = axio;
692	}
693		break;
694
695	default:
696		break;
697	} /* switch */
698
699	kfree(scfg);
700
701	kfree(axio);
702
703/*
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);
709	}
710*/
711	return rc;
712}
713
714static int vfe_init(struct msm_vfe_callback *presp,
715	struct platform_device *dev)
716{
717	int rc = 0;
718
719	rc = vfe_cmd_init(presp, dev, vfe_syncdata);
720	if (rc < 0)
721		return rc;
722
723	/* Bring up all the required GPIOs and Clocks */
724	return msm_camio_enable(dev);
725}
726
727void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
728{
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;
736}
737