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