root/drivers/media/platform/davinci/vpbe_venc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_state
  2. venc_read
  3. venc_write
  4. venc_modify
  5. vdaccfg_write
  6. venc_set_dac
  7. venc_enabledigitaloutput
  8. venc_enable_vpss_clock
  9. venc_set_ntsc
  10. venc_set_pal
  11. venc_set_480p59_94
  12. venc_set_576p50
  13. venc_set_720p60_internal
  14. venc_set_1080i30_internal
  15. venc_s_std_output
  16. venc_s_dv_timings
  17. venc_s_routing
  18. venc_ioctl
  19. venc_initialize
  20. venc_device_get
  21. venc_sub_dev_init
  22. venc_probe
  23. venc_remove

   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 
  30 static 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 
  46 MODULE_DEVICE_TABLE(platform, vpbe_venc_devtype);
  47 
  48 static int debug = 2;
  49 module_param(debug, int, 0644);
  50 MODULE_PARM_DESC(debug, "Debug level 0-2");
  51 
  52 struct 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 
  65 static inline struct venc_state *to_state(struct v4l2_subdev *sd)
  66 {
  67         return container_of(sd, struct venc_state, sd);
  68 }
  69 
  70 static 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 
  77 static 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 
  86 static 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 
  96 static 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  */
 111 static 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 
 133 static 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 
 192 static void
 193 venc_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  */
 216 static 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  */
 263 static 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  */
 315 static 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  */
 363 static 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  */
 410 static 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  */
 439 static 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 
 466 static 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 
 478 static 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 
 509 static 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 
 524 static long venc_ioctl(struct v4l2_subdev *sd,
 525                         unsigned int cmd,
 526                         void *arg)
 527 {
 528         u32 val;
 529 
 530         switch (cmd) {
 531         case VENC_GET_FLD:
 532                 val = venc_read(sd, VENC_VSTAT);
 533                 *((int *)arg) = ((val & VENC_VSTAT_FIDST) ==
 534                 VENC_VSTAT_FIDST);
 535                 break;
 536         default:
 537                 v4l2_err(sd, "Wrong IOCTL cmd\n");
 538                 break;
 539         }
 540 
 541         return 0;
 542 }
 543 
 544 static const struct v4l2_subdev_core_ops venc_core_ops = {
 545         .ioctl      = venc_ioctl,
 546 };
 547 
 548 static const struct v4l2_subdev_video_ops venc_video_ops = {
 549         .s_routing = venc_s_routing,
 550         .s_std_output = venc_s_std_output,
 551         .s_dv_timings = venc_s_dv_timings,
 552 };
 553 
 554 static const struct v4l2_subdev_ops venc_ops = {
 555         .core = &venc_core_ops,
 556         .video = &venc_video_ops,
 557 };
 558 
 559 static int venc_initialize(struct v4l2_subdev *sd)
 560 {
 561         struct venc_state *venc = to_state(sd);
 562         int ret;
 563 
 564         /* Set default to output to composite and std to NTSC */
 565         venc->output = 0;
 566         venc->std = V4L2_STD_525_60;
 567 
 568         ret = venc_s_routing(sd, 0, venc->output, 0);
 569         if (ret < 0) {
 570                 v4l2_err(sd, "Error setting output during init\n");
 571                 return -EINVAL;
 572         }
 573 
 574         ret = venc_s_std_output(sd, venc->std);
 575         if (ret < 0) {
 576                 v4l2_err(sd, "Error setting std during init\n");
 577                 return -EINVAL;
 578         }
 579 
 580         return ret;
 581 }
 582 
 583 static int venc_device_get(struct device *dev, void *data)
 584 {
 585         struct platform_device *pdev = to_platform_device(dev);
 586         struct venc_state **venc = data;
 587 
 588         if (strstr(pdev->name, "vpbe-venc") != NULL)
 589                 *venc = platform_get_drvdata(pdev);
 590 
 591         return 0;
 592 }
 593 
 594 struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev,
 595                 const char *venc_name)
 596 {
 597         struct venc_state *venc = NULL;
 598 
 599         bus_for_each_dev(&platform_bus_type, NULL, &venc,
 600                         venc_device_get);
 601         if (venc == NULL)
 602                 return NULL;
 603 
 604         v4l2_subdev_init(&venc->sd, &venc_ops);
 605 
 606         strscpy(venc->sd.name, venc_name, sizeof(venc->sd.name));
 607         if (v4l2_device_register_subdev(v4l2_dev, &venc->sd) < 0) {
 608                 v4l2_err(v4l2_dev,
 609                         "vpbe unable to register venc sub device\n");
 610                 return NULL;
 611         }
 612         if (venc_initialize(&venc->sd)) {
 613                 v4l2_err(v4l2_dev,
 614                         "vpbe venc initialization failed\n");
 615                 return NULL;
 616         }
 617 
 618         return &venc->sd;
 619 }
 620 EXPORT_SYMBOL(venc_sub_dev_init);
 621 
 622 static int venc_probe(struct platform_device *pdev)
 623 {
 624         const struct platform_device_id *pdev_id;
 625         struct venc_state *venc;
 626         struct resource *res;
 627 
 628         if (!pdev->dev.platform_data) {
 629                 dev_err(&pdev->dev, "No platform data for VENC sub device");
 630                 return -EINVAL;
 631         }
 632 
 633         pdev_id = platform_get_device_id(pdev);
 634         if (!pdev_id)
 635                 return -EINVAL;
 636 
 637         venc = devm_kzalloc(&pdev->dev, sizeof(struct venc_state), GFP_KERNEL);
 638         if (venc == NULL)
 639                 return -ENOMEM;
 640 
 641         venc->venc_type = pdev_id->driver_data;
 642         venc->pdev = &pdev->dev;
 643         venc->pdata = pdev->dev.platform_data;
 644 
 645         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 646 
 647         venc->venc_base = devm_ioremap_resource(&pdev->dev, res);
 648         if (IS_ERR(venc->venc_base))
 649                 return PTR_ERR(venc->venc_base);
 650 
 651         if (venc->venc_type != VPBE_VERSION_1) {
 652                 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 653 
 654                 venc->vdaccfg_reg = devm_ioremap_resource(&pdev->dev, res);
 655                 if (IS_ERR(venc->vdaccfg_reg))
 656                         return PTR_ERR(venc->vdaccfg_reg);
 657         }
 658         spin_lock_init(&venc->lock);
 659         platform_set_drvdata(pdev, venc);
 660         dev_notice(venc->pdev, "VENC sub device probe success\n");
 661 
 662         return 0;
 663 }
 664 
 665 static int venc_remove(struct platform_device *pdev)
 666 {
 667         return 0;
 668 }
 669 
 670 static struct platform_driver venc_driver = {
 671         .probe          = venc_probe,
 672         .remove         = venc_remove,
 673         .driver         = {
 674                 .name   = MODULE_NAME,
 675         },
 676         .id_table       = vpbe_venc_devtype
 677 };
 678 
 679 module_platform_driver(venc_driver);
 680 
 681 MODULE_LICENSE("GPL");
 682 MODULE_DESCRIPTION("VPBE VENC Driver");
 683 MODULE_AUTHOR("Texas Instruments");

/* [<][>][^][v][top][bottom][index][help] */