1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/ctype.h>
17#include <linux/delay.h>
18#include <linux/device.h>
19#include <linux/interrupt.h>
20#include <linux/platform_device.h>
21#include <linux/videodev2.h>
22#include <linux/slab.h>
23
24#ifdef CONFIG_ARCH_DAVINCI
25#include <mach/hardware.h>
26#include <mach/mux.h>
27#endif
28
29#include <linux/platform_data/i2c-davinci.h>
30
31#include <linux/io.h>
32
33#include <media/davinci/vpbe_types.h>
34#include <media/davinci/vpbe_venc.h>
35#include <media/davinci/vpss.h>
36#include <media/v4l2-device.h>
37
38#include "vpbe_venc_regs.h"
39
40#define MODULE_NAME "davinci-vpbe-venc"
41
42static const struct platform_device_id vpbe_venc_devtype[] = {
43 {
44 .name = DM644X_VPBE_VENC_SUBDEV_NAME,
45 .driver_data = VPBE_VERSION_1,
46 }, {
47 .name = DM365_VPBE_VENC_SUBDEV_NAME,
48 .driver_data = VPBE_VERSION_2,
49 }, {
50 .name = DM355_VPBE_VENC_SUBDEV_NAME,
51 .driver_data = VPBE_VERSION_3,
52 },
53 {
54
55 }
56};
57
58MODULE_DEVICE_TABLE(platform, vpbe_venc_devtype);
59
60static int debug = 2;
61module_param(debug, int, 0644);
62MODULE_PARM_DESC(debug, "Debug level 0-2");
63
64struct venc_state {
65 struct v4l2_subdev sd;
66 struct venc_callback *callback;
67 struct venc_platform_data *pdata;
68 struct device *pdev;
69 u32 output;
70 v4l2_std_id std;
71 spinlock_t lock;
72 void __iomem *venc_base;
73 void __iomem *vdaccfg_reg;
74 enum vpbe_version venc_type;
75};
76
77static inline struct venc_state *to_state(struct v4l2_subdev *sd)
78{
79 return container_of(sd, struct venc_state, sd);
80}
81
82static inline u32 venc_read(struct v4l2_subdev *sd, u32 offset)
83{
84 struct venc_state *venc = to_state(sd);
85
86 return readl(venc->venc_base + offset);
87}
88
89static inline u32 venc_write(struct v4l2_subdev *sd, u32 offset, u32 val)
90{
91 struct venc_state *venc = to_state(sd);
92
93 writel(val, (venc->venc_base + offset));
94
95 return val;
96}
97
98static inline u32 venc_modify(struct v4l2_subdev *sd, u32 offset,
99 u32 val, u32 mask)
100{
101 u32 new_val = (venc_read(sd, offset) & ~mask) | (val & mask);
102
103 venc_write(sd, offset, new_val);
104
105 return new_val;
106}
107
108static inline u32 vdaccfg_write(struct v4l2_subdev *sd, u32 val)
109{
110 struct venc_state *venc = to_state(sd);
111
112 writel(val, venc->vdaccfg_reg);
113
114 val = readl(venc->vdaccfg_reg);
115
116 return val;
117}
118
119#define VDAC_COMPONENT 0x543
120#define VDAC_S_VIDEO 0x210
121
122
123static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index)
124{
125 switch (out_index) {
126 case 0:
127 v4l2_dbg(debug, 1, sd, "Setting output to Composite\n");
128 venc_write(sd, VENC_DACSEL, 0);
129 break;
130 case 1:
131 v4l2_dbg(debug, 1, sd, "Setting output to Component\n");
132 venc_write(sd, VENC_DACSEL, VDAC_COMPONENT);
133 break;
134 case 2:
135 v4l2_dbg(debug, 1, sd, "Setting output to S-video\n");
136 venc_write(sd, VENC_DACSEL, VDAC_S_VIDEO);
137 break;
138 default:
139 return -EINVAL;
140 }
141
142 return 0;
143}
144
145static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable)
146{
147 struct venc_state *venc = to_state(sd);
148
149 v4l2_dbg(debug, 2, sd, "venc_enabledigitaloutput\n");
150
151 if (benable) {
152 venc_write(sd, VENC_VMOD, 0);
153 venc_write(sd, VENC_CVBS, 0);
154 venc_write(sd, VENC_LCDOUT, 0);
155 venc_write(sd, VENC_HSPLS, 0);
156 venc_write(sd, VENC_HSTART, 0);
157 venc_write(sd, VENC_HVALID, 0);
158 venc_write(sd, VENC_HINT, 0);
159 venc_write(sd, VENC_VSPLS, 0);
160 venc_write(sd, VENC_VSTART, 0);
161 venc_write(sd, VENC_VVALID, 0);
162 venc_write(sd, VENC_VINT, 0);
163 venc_write(sd, VENC_YCCCTL, 0);
164 venc_write(sd, VENC_DACSEL, 0);
165
166 } else {
167 venc_write(sd, VENC_VMOD, 0);
168
169 venc_write(sd, VENC_VIDCTL, 0x141);
170
171
172 venc_write(sd, VENC_SYNCCTL, 0);
173
174
175 venc_write(sd, VENC_DCLKCTL, 0);
176 venc_write(sd, VENC_DRGBX1, 0x0000057C);
177
178
179 venc_write(sd, VENC_LCDOUT, 0);
180 if (venc->venc_type != VPBE_VERSION_3)
181 venc_write(sd, VENC_CMPNT, 0x100);
182 venc_write(sd, VENC_HSPLS, 0);
183 venc_write(sd, VENC_HINT, 0);
184 venc_write(sd, VENC_HSTART, 0);
185 venc_write(sd, VENC_HVALID, 0);
186
187 venc_write(sd, VENC_VSPLS, 0);
188 venc_write(sd, VENC_VINT, 0);
189 venc_write(sd, VENC_VSTART, 0);
190 venc_write(sd, VENC_VVALID, 0);
191
192 venc_write(sd, VENC_HSDLY, 0);
193 venc_write(sd, VENC_VSDLY, 0);
194
195 venc_write(sd, VENC_YCCCTL, 0);
196 venc_write(sd, VENC_VSTARTA, 0);
197
198
199 venc_write(sd, VENC_OSDCLK0, 1);
200 venc_write(sd, VENC_OSDCLK1, 2);
201 }
202}
203
204static void
205venc_enable_vpss_clock(int venc_type,
206 enum vpbe_enc_timings_type type,
207 unsigned int pclock)
208{
209 if (venc_type == VPBE_VERSION_1)
210 return;
211
212 if (venc_type == VPBE_VERSION_2 && (type == VPBE_ENC_STD || (type ==
213 VPBE_ENC_DV_TIMINGS && pclock <= 27000000))) {
214 vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
215 vpss_enable_clock(VPSS_VPBE_CLOCK, 1);
216 return;
217 }
218
219 if (venc_type == VPBE_VERSION_3 && type == VPBE_ENC_STD)
220 vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 0);
221}
222
223#define VDAC_CONFIG_SD_V3 0x0E21A6B6
224#define VDAC_CONFIG_SD_V2 0x081141CF
225
226
227
228static int venc_set_ntsc(struct v4l2_subdev *sd)
229{
230 struct venc_state *venc = to_state(sd);
231 struct venc_platform_data *pdata = venc->pdata;
232
233 v4l2_dbg(debug, 2, sd, "venc_set_ntsc\n");
234
235
236 vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
237 if (pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_525_60) < 0)
238 return -EINVAL;
239
240 venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_STD, V4L2_STD_525_60);
241 venc_enabledigitaloutput(sd, 0);
242
243 if (venc->venc_type == VPBE_VERSION_3) {
244 venc_write(sd, VENC_CLKCTL, 0x01);
245 venc_write(sd, VENC_VIDCTL, 0);
246 vdaccfg_write(sd, VDAC_CONFIG_SD_V3);
247 } else if (venc->venc_type == VPBE_VERSION_2) {
248 venc_write(sd, VENC_CLKCTL, 0x01);
249 venc_write(sd, VENC_VIDCTL, 0);
250 vdaccfg_write(sd, VDAC_CONFIG_SD_V2);
251 } else {
252
253 venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
254
255 venc_write(sd, VENC_YCCCTL, 0x1);
256 venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ);
257 venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS);
258 }
259
260 venc_write(sd, VENC_VMOD, 0);
261 venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
262 VENC_VMOD_VIE);
263 venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
264 venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_TVTYP_SHIFT),
265 VENC_VMOD_TVTYP);
266 venc_write(sd, VENC_DACTST, 0x0);
267 venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
268
269 return 0;
270}
271
272
273
274
275static int venc_set_pal(struct v4l2_subdev *sd)
276{
277 struct venc_state *venc = to_state(sd);
278
279 v4l2_dbg(debug, 2, sd, "venc_set_pal\n");
280
281
282 vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
283 if (venc->pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_625_50) < 0)
284 return -EINVAL;
285
286 venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_STD, V4L2_STD_625_50);
287 venc_enabledigitaloutput(sd, 0);
288
289 if (venc->venc_type == VPBE_VERSION_3) {
290 venc_write(sd, VENC_CLKCTL, 0x1);
291 venc_write(sd, VENC_VIDCTL, 0);
292 vdaccfg_write(sd, VDAC_CONFIG_SD_V3);
293 } else if (venc->venc_type == VPBE_VERSION_2) {
294 venc_write(sd, VENC_CLKCTL, 0x1);
295 venc_write(sd, VENC_VIDCTL, 0);
296 vdaccfg_write(sd, VDAC_CONFIG_SD_V2);
297 } else {
298
299 venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
300
301 venc_write(sd, VENC_YCCCTL, 0x1);
302 }
303
304 venc_modify(sd, VENC_SYNCCTL, 1 << VENC_SYNCCTL_OVD_SHIFT,
305 VENC_SYNCCTL_OVD);
306 venc_write(sd, VENC_VMOD, 0);
307 venc_modify(sd, VENC_VMOD,
308 (1 << VENC_VMOD_VIE_SHIFT),
309 VENC_VMOD_VIE);
310 venc_modify(sd, VENC_VMOD,
311 (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
312 venc_modify(sd, VENC_VMOD,
313 (1 << VENC_VMOD_TVTYP_SHIFT),
314 VENC_VMOD_TVTYP);
315 venc_write(sd, VENC_DACTST, 0x0);
316 venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
317
318 return 0;
319}
320
321#define VDAC_CONFIG_HD_V2 0x081141EF
322
323
324
325
326
327static int venc_set_480p59_94(struct v4l2_subdev *sd)
328{
329 struct venc_state *venc = to_state(sd);
330 struct venc_platform_data *pdata = venc->pdata;
331
332 v4l2_dbg(debug, 2, sd, "venc_set_480p59_94\n");
333 if (venc->venc_type != VPBE_VERSION_1 &&
334 venc->venc_type != VPBE_VERSION_2)
335 return -EINVAL;
336
337
338 if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 27000000) < 0)
339 return -EINVAL;
340
341 venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 27000000);
342 venc_enabledigitaloutput(sd, 0);
343
344 if (venc->venc_type == VPBE_VERSION_2)
345 vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
346 venc_write(sd, VENC_OSDCLK0, 0);
347 venc_write(sd, VENC_OSDCLK1, 1);
348
349 if (venc->venc_type == VPBE_VERSION_1) {
350 venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
351 VENC_VDPRO_DAFRQ);
352 venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
353 VENC_VDPRO_DAUPS);
354 }
355
356 venc_write(sd, VENC_VMOD, 0);
357 venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
358 VENC_VMOD_VIE);
359 venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
360 venc_modify(sd, VENC_VMOD, (HDTV_525P << VENC_VMOD_TVTYP_SHIFT),
361 VENC_VMOD_TVTYP);
362 venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
363 VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
364
365 venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
366
367 return 0;
368}
369
370
371
372
373
374
375static int venc_set_576p50(struct v4l2_subdev *sd)
376{
377 struct venc_state *venc = to_state(sd);
378 struct venc_platform_data *pdata = venc->pdata;
379
380 v4l2_dbg(debug, 2, sd, "venc_set_576p50\n");
381
382 if (venc->venc_type != VPBE_VERSION_1 &&
383 venc->venc_type != VPBE_VERSION_2)
384 return -EINVAL;
385
386 if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 27000000) < 0)
387 return -EINVAL;
388
389 venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 27000000);
390 venc_enabledigitaloutput(sd, 0);
391
392 if (venc->venc_type == VPBE_VERSION_2)
393 vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
394
395 venc_write(sd, VENC_OSDCLK0, 0);
396 venc_write(sd, VENC_OSDCLK1, 1);
397
398 if (venc->venc_type == VPBE_VERSION_1) {
399 venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
400 VENC_VDPRO_DAFRQ);
401 venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
402 VENC_VDPRO_DAUPS);
403 }
404
405 venc_write(sd, VENC_VMOD, 0);
406 venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
407 VENC_VMOD_VIE);
408 venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
409 venc_modify(sd, VENC_VMOD, (HDTV_625P << VENC_VMOD_TVTYP_SHIFT),
410 VENC_VMOD_TVTYP);
411
412 venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
413 VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
414 venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
415
416 return 0;
417}
418
419
420
421
422static int venc_set_720p60_internal(struct v4l2_subdev *sd)
423{
424 struct venc_state *venc = to_state(sd);
425 struct venc_platform_data *pdata = venc->pdata;
426
427 if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 74250000) < 0)
428 return -EINVAL;
429
430 venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 74250000);
431 venc_enabledigitaloutput(sd, 0);
432
433 venc_write(sd, VENC_OSDCLK0, 0);
434 venc_write(sd, VENC_OSDCLK1, 1);
435
436 venc_write(sd, VENC_VMOD, 0);
437
438 venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
439 VENC_VMOD_VIE);
440 venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
441 venc_modify(sd, VENC_VMOD, (HDTV_720P << VENC_VMOD_TVTYP_SHIFT),
442 VENC_VMOD_TVTYP);
443 venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
444 venc_write(sd, VENC_XHINTVL, 0);
445 return 0;
446}
447
448
449
450
451static int venc_set_1080i30_internal(struct v4l2_subdev *sd)
452{
453 struct venc_state *venc = to_state(sd);
454 struct venc_platform_data *pdata = venc->pdata;
455
456 if (pdata->setup_clock(VPBE_ENC_DV_TIMINGS, 74250000) < 0)
457 return -EINVAL;
458
459 venc_enable_vpss_clock(venc->venc_type, VPBE_ENC_DV_TIMINGS, 74250000);
460 venc_enabledigitaloutput(sd, 0);
461
462 venc_write(sd, VENC_OSDCLK0, 0);
463 venc_write(sd, VENC_OSDCLK1, 1);
464
465
466 venc_write(sd, VENC_VMOD, 0);
467
468 venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
469 VENC_VMOD_VIE);
470 venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
471 venc_modify(sd, VENC_VMOD, (HDTV_1080I << VENC_VMOD_TVTYP_SHIFT),
472 VENC_VMOD_TVTYP);
473 venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
474 venc_write(sd, VENC_XHINTVL, 0);
475 return 0;
476}
477
478static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
479{
480 v4l2_dbg(debug, 1, sd, "venc_s_std_output\n");
481
482 if (norm & V4L2_STD_525_60)
483 return venc_set_ntsc(sd);
484 else if (norm & V4L2_STD_625_50)
485 return venc_set_pal(sd);
486
487 return -EINVAL;
488}
489
490static int venc_s_dv_timings(struct v4l2_subdev *sd,
491 struct v4l2_dv_timings *dv_timings)
492{
493 struct venc_state *venc = to_state(sd);
494 u32 height = dv_timings->bt.height;
495 int ret;
496
497 v4l2_dbg(debug, 1, sd, "venc_s_dv_timings\n");
498
499 if (height == 576)
500 return venc_set_576p50(sd);
501 else if (height == 480)
502 return venc_set_480p59_94(sd);
503 else if ((height == 720) &&
504 (venc->venc_type == VPBE_VERSION_2)) {
505
506 ret = venc_set_720p60_internal(sd);
507
508 vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
509 return ret;
510 } else if ((height == 1080) &&
511 (venc->venc_type == VPBE_VERSION_2)) {
512
513 ret = venc_set_1080i30_internal(sd);
514
515 vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
516 return ret;
517 }
518 return -EINVAL;
519}
520
521static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output,
522 u32 config)
523{
524 struct venc_state *venc = to_state(sd);
525 int ret;
526
527 v4l2_dbg(debug, 1, sd, "venc_s_routing\n");
528
529 ret = venc_set_dac(sd, output);
530 if (!ret)
531 venc->output = output;
532
533 return ret;
534}
535
536static long venc_ioctl(struct v4l2_subdev *sd,
537 unsigned int cmd,
538 void *arg)
539{
540 u32 val;
541
542 switch (cmd) {
543 case VENC_GET_FLD:
544 val = venc_read(sd, VENC_VSTAT);
545 *((int *)arg) = ((val & VENC_VSTAT_FIDST) ==
546 VENC_VSTAT_FIDST);
547 break;
548 default:
549 v4l2_err(sd, "Wrong IOCTL cmd\n");
550 break;
551 }
552
553 return 0;
554}
555
556static const struct v4l2_subdev_core_ops venc_core_ops = {
557 .ioctl = venc_ioctl,
558};
559
560static const struct v4l2_subdev_video_ops venc_video_ops = {
561 .s_routing = venc_s_routing,
562 .s_std_output = venc_s_std_output,
563 .s_dv_timings = venc_s_dv_timings,
564};
565
566static const struct v4l2_subdev_ops venc_ops = {
567 .core = &venc_core_ops,
568 .video = &venc_video_ops,
569};
570
571static int venc_initialize(struct v4l2_subdev *sd)
572{
573 struct venc_state *venc = to_state(sd);
574 int ret;
575
576
577 venc->output = 0;
578 venc->std = V4L2_STD_525_60;
579
580 ret = venc_s_routing(sd, 0, venc->output, 0);
581 if (ret < 0) {
582 v4l2_err(sd, "Error setting output during init\n");
583 return -EINVAL;
584 }
585
586 ret = venc_s_std_output(sd, venc->std);
587 if (ret < 0) {
588 v4l2_err(sd, "Error setting std during init\n");
589 return -EINVAL;
590 }
591
592 return ret;
593}
594
595static int venc_device_get(struct device *dev, void *data)
596{
597 struct platform_device *pdev = to_platform_device(dev);
598 struct venc_state **venc = data;
599
600 if (strstr(pdev->name, "vpbe-venc") != NULL)
601 *venc = platform_get_drvdata(pdev);
602
603 return 0;
604}
605
606struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev,
607 const char *venc_name)
608{
609 struct venc_state *venc = NULL;
610
611 bus_for_each_dev(&platform_bus_type, NULL, &venc,
612 venc_device_get);
613 if (venc == NULL)
614 return NULL;
615
616 v4l2_subdev_init(&venc->sd, &venc_ops);
617
618 strcpy(venc->sd.name, venc_name);
619 if (v4l2_device_register_subdev(v4l2_dev, &venc->sd) < 0) {
620 v4l2_err(v4l2_dev,
621 "vpbe unable to register venc sub device\n");
622 return NULL;
623 }
624 if (venc_initialize(&venc->sd)) {
625 v4l2_err(v4l2_dev,
626 "vpbe venc initialization failed\n");
627 return NULL;
628 }
629
630 return &venc->sd;
631}
632EXPORT_SYMBOL(venc_sub_dev_init);
633
634static int venc_probe(struct platform_device *pdev)
635{
636 const struct platform_device_id *pdev_id;
637 struct venc_state *venc;
638 struct resource *res;
639
640 if (!pdev->dev.platform_data) {
641 dev_err(&pdev->dev, "No platform data for VENC sub device");
642 return -EINVAL;
643 }
644
645 pdev_id = platform_get_device_id(pdev);
646 if (!pdev_id)
647 return -EINVAL;
648
649 venc = devm_kzalloc(&pdev->dev, sizeof(struct venc_state), GFP_KERNEL);
650 if (venc == NULL)
651 return -ENOMEM;
652
653 venc->venc_type = pdev_id->driver_data;
654 venc->pdev = &pdev->dev;
655 venc->pdata = pdev->dev.platform_data;
656
657 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
658
659 venc->venc_base = devm_ioremap_resource(&pdev->dev, res);
660 if (IS_ERR(venc->venc_base))
661 return PTR_ERR(venc->venc_base);
662
663 if (venc->venc_type != VPBE_VERSION_1) {
664 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
665
666 venc->vdaccfg_reg = devm_ioremap_resource(&pdev->dev, res);
667 if (IS_ERR(venc->vdaccfg_reg))
668 return PTR_ERR(venc->vdaccfg_reg);
669 }
670 spin_lock_init(&venc->lock);
671 platform_set_drvdata(pdev, venc);
672 dev_notice(venc->pdev, "VENC sub device probe success\n");
673
674 return 0;
675}
676
677static int venc_remove(struct platform_device *pdev)
678{
679 return 0;
680}
681
682static struct platform_driver venc_driver = {
683 .probe = venc_probe,
684 .remove = venc_remove,
685 .driver = {
686 .name = MODULE_NAME,
687 },
688 .id_table = vpbe_venc_devtype
689};
690
691module_platform_driver(venc_driver);
692
693MODULE_LICENSE("GPL");
694MODULE_DESCRIPTION("VPBE VENC Driver");
695MODULE_AUTHOR("Texas Instruments");
696