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