]>
Commit | Line | Data |
---|---|---|
eb7b797b BS |
1 | /* |
2 | * Copyright (C) 2008-2009 QUALCOMM Incorporated. | |
3 | */ | |
5a0e3ad6 | 4 | #include <linux/slab.h> |
eb7b797b BS |
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 | ||
13 | struct mutex vfe_lock; | |
14 | static void *vfe_syncdata; | |
15 | ||
16 | static int vfe_enable(struct camera_enable_cmd *enable) | |
17 | { | |
18 | int rc = 0; | |
19 | return rc; | |
20 | } | |
21 | ||
22 | static 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 | ||
33 | static 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 | ||
43 | static 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 | ||
101 | static 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 | ||
520 | static 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 | ||
37a18632 JL |
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); | |
eb7b797b BS |
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 | ||
37a18632 JL |
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); | |
eb7b797b BS |
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 | ||
37a18632 JL |
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); | |
eb7b797b BS |
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 | ||
714 | static 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 | ||
727 | void 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 | } |