linux/drivers/media/video/davinci/vpbe.c
<<
>>
Prefs
   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/kernel.h>
  18#include <linux/init.h>
  19#include <linux/module.h>
  20#include <linux/errno.h>
  21#include <linux/fs.h>
  22#include <linux/string.h>
  23#include <linux/wait.h>
  24#include <linux/time.h>
  25#include <linux/platform_device.h>
  26#include <linux/io.h>
  27#include <linux/slab.h>
  28#include <linux/clk.h>
  29#include <linux/err.h>
  30
  31#include <media/v4l2-device.h>
  32#include <media/davinci/vpbe_types.h>
  33#include <media/davinci/vpbe.h>
  34#include <media/davinci/vpss.h>
  35#include <media/davinci/vpbe_venc.h>
  36
  37#define VPBE_DEFAULT_OUTPUT     "Composite"
  38#define VPBE_DEFAULT_MODE       "ntsc"
  39
  40static char *def_output = VPBE_DEFAULT_OUTPUT;
  41static char *def_mode = VPBE_DEFAULT_MODE;
  42static int debug;
  43
  44module_param(def_output, charp, S_IRUGO);
  45module_param(def_mode, charp, S_IRUGO);
  46module_param(debug, int, 0644);
  47
  48MODULE_PARM_DESC(def_output, "vpbe output name (default:Composite)");
  49MODULE_PARM_DESC(def_mode, "vpbe output mode name (default:ntsc");
  50MODULE_PARM_DESC(debug, "Debug level 0-1");
  51
  52MODULE_DESCRIPTION("TI DMXXX VPBE Display controller");
  53MODULE_LICENSE("GPL");
  54MODULE_AUTHOR("Texas Instruments");
  55
  56/**
  57 * vpbe_current_encoder_info - Get config info for current encoder
  58 * @vpbe_dev - vpbe device ptr
  59 *
  60 * Return ptr to current encoder config info
  61 */
  62static struct encoder_config_info*
  63vpbe_current_encoder_info(struct vpbe_device *vpbe_dev)
  64{
  65        struct vpbe_config *cfg = vpbe_dev->cfg;
  66        int index = vpbe_dev->current_sd_index;
  67
  68        return ((index == 0) ? &cfg->venc :
  69                                &cfg->ext_encoders[index-1]);
  70}
  71
  72/**
  73 * vpbe_find_encoder_sd_index - Given a name find encoder sd index
  74 *
  75 * @vpbe_config - ptr to vpbe cfg
  76 * @output_index - index used by application
  77 *
  78 * Return sd index of the encoder
  79 */
  80static int vpbe_find_encoder_sd_index(struct vpbe_config *cfg,
  81                             int index)
  82{
  83        char *encoder_name = cfg->outputs[index].subdev_name;
  84        int i;
  85
  86        /* Venc is always first */
  87        if (!strcmp(encoder_name, cfg->venc.module_name))
  88                return 0;
  89
  90        for (i = 0; i < cfg->num_ext_encoders; i++) {
  91                if (!strcmp(encoder_name,
  92                     cfg->ext_encoders[i].module_name))
  93                        return i+1;
  94        }
  95
  96        return -EINVAL;
  97}
  98
  99/**
 100 * vpbe_g_cropcap - Get crop capabilities of the display
 101 * @vpbe_dev - vpbe device ptr
 102 * @cropcap - cropcap is a ptr to struct v4l2_cropcap
 103 *
 104 * Update the crop capabilities in crop cap for current
 105 * mode
 106 */
 107static int vpbe_g_cropcap(struct vpbe_device *vpbe_dev,
 108                          struct v4l2_cropcap *cropcap)
 109{
 110        if (NULL == cropcap)
 111                return -EINVAL;
 112        cropcap->bounds.left = 0;
 113        cropcap->bounds.top = 0;
 114        cropcap->bounds.width = vpbe_dev->current_timings.xres;
 115        cropcap->bounds.height = vpbe_dev->current_timings.yres;
 116        cropcap->defrect = cropcap->bounds;
 117
 118        return 0;
 119}
 120
 121/**
 122 * vpbe_enum_outputs - enumerate outputs
 123 * @vpbe_dev - vpbe device ptr
 124 * @output - ptr to v4l2_output structure
 125 *
 126 * Enumerates the outputs available at the vpbe display
 127 * returns the status, -EINVAL if end of output list
 128 */
 129static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev,
 130                             struct v4l2_output *output)
 131{
 132        struct vpbe_config *cfg = vpbe_dev->cfg;
 133        int temp_index = output->index;
 134
 135        if (temp_index >= cfg->num_outputs)
 136                return -EINVAL;
 137
 138        *output = cfg->outputs[temp_index].output;
 139        output->index = temp_index;
 140
 141        return 0;
 142}
 143
 144static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode)
 145{
 146        struct vpbe_config *cfg = vpbe_dev->cfg;
 147        struct vpbe_enc_mode_info var;
 148        int curr_output = vpbe_dev->current_out_index;
 149        int i;
 150
 151        if (NULL == mode)
 152                return -EINVAL;
 153
 154        for (i = 0; i < cfg->outputs[curr_output].num_modes; i++) {
 155                var = cfg->outputs[curr_output].modes[i];
 156                if (!strcmp(mode, var.name)) {
 157                        vpbe_dev->current_timings = var;
 158                        return 0;
 159                }
 160        }
 161
 162        return -EINVAL;
 163}
 164
 165static int vpbe_get_current_mode_info(struct vpbe_device *vpbe_dev,
 166                                      struct vpbe_enc_mode_info *mode_info)
 167{
 168        if (NULL == mode_info)
 169                return -EINVAL;
 170
 171        *mode_info = vpbe_dev->current_timings;
 172
 173        return 0;
 174}
 175
 176static int vpbe_get_dv_preset_info(struct vpbe_device *vpbe_dev,
 177                                   unsigned int dv_preset)
 178{
 179        struct vpbe_config *cfg = vpbe_dev->cfg;
 180        struct vpbe_enc_mode_info var;
 181        int curr_output = vpbe_dev->current_out_index;
 182        int i;
 183
 184        for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
 185                var = cfg->outputs[curr_output].modes[i];
 186                if ((var.timings_type & VPBE_ENC_DV_PRESET) &&
 187                  (var.timings.dv_preset == dv_preset)) {
 188                        vpbe_dev->current_timings = var;
 189                        return 0;
 190                }
 191        }
 192
 193        return -EINVAL;
 194}
 195
 196/* Get std by std id */
 197static int vpbe_get_std_info(struct vpbe_device *vpbe_dev,
 198                             v4l2_std_id std_id)
 199{
 200        struct vpbe_config *cfg = vpbe_dev->cfg;
 201        struct vpbe_enc_mode_info var;
 202        int curr_output = vpbe_dev->current_out_index;
 203        int i;
 204
 205        for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
 206                var = cfg->outputs[curr_output].modes[i];
 207                if ((var.timings_type & VPBE_ENC_STD) &&
 208                  (var.timings.std_id & std_id)) {
 209                        vpbe_dev->current_timings = var;
 210                        return 0;
 211                }
 212        }
 213
 214        return -EINVAL;
 215}
 216
 217static int vpbe_get_std_info_by_name(struct vpbe_device *vpbe_dev,
 218                                char *std_name)
 219{
 220        struct vpbe_config *cfg = vpbe_dev->cfg;
 221        struct vpbe_enc_mode_info var;
 222        int curr_output = vpbe_dev->current_out_index;
 223        int i;
 224
 225        for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
 226                var = cfg->outputs[curr_output].modes[i];
 227                if (!strcmp(var.name, std_name)) {
 228                        vpbe_dev->current_timings = var;
 229                        return 0;
 230                }
 231        }
 232
 233        return -EINVAL;
 234}
 235
 236/**
 237 * vpbe_set_output - Set output
 238 * @vpbe_dev - vpbe device ptr
 239 * @index - index of output
 240 *
 241 * Set vpbe output to the output specified by the index
 242 */
 243static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index)
 244{
 245        struct encoder_config_info *curr_enc_info =
 246                        vpbe_current_encoder_info(vpbe_dev);
 247        struct vpbe_config *cfg = vpbe_dev->cfg;
 248        int enc_out_index;
 249        int sd_index;
 250        int ret = 0;
 251
 252        if (index >= cfg->num_outputs)
 253                return -EINVAL;
 254
 255        mutex_lock(&vpbe_dev->lock);
 256
 257        sd_index = vpbe_dev->current_sd_index;
 258        enc_out_index = cfg->outputs[index].output.index;
 259        /*
 260         * Currently we switch the encoder based on output selected
 261         * by the application. If media controller is implemented later
 262         * there is will be an API added to setup_link between venc
 263         * and external encoder. So in that case below comparison always
 264         * match and encoder will not be switched. But if application
 265         * chose not to use media controller, then this provides current
 266         * way of switching encoder at the venc output.
 267         */
 268        if (strcmp(curr_enc_info->module_name,
 269                   cfg->outputs[index].subdev_name)) {
 270                /* Need to switch the encoder at the output */
 271                sd_index = vpbe_find_encoder_sd_index(cfg, index);
 272                if (sd_index < 0) {
 273                        ret = -EINVAL;
 274                        goto out;
 275                }
 276
 277                if (ret)
 278                        goto out;
 279        }
 280
 281        /* Set output at the encoder */
 282        ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
 283                                       s_routing, 0, enc_out_index, 0);
 284        if (ret)
 285                goto out;
 286
 287        /*
 288         * It is assumed that venc or extenal encoder will set a default
 289         * mode in the sub device. For external encoder or LCD pannel output,
 290         * we also need to set up the lcd port for the required mode. So setup
 291         * the lcd port for the default mode that is configured in the board
 292         * arch/arm/mach-davinci/board-dm355-evm.setup file for the external
 293         * encoder.
 294         */
 295        ret = vpbe_get_mode_info(vpbe_dev,
 296                                 cfg->outputs[index].default_mode);
 297        if (!ret) {
 298                struct osd_state *osd_device = vpbe_dev->osd_device;
 299
 300                osd_device->ops.set_left_margin(osd_device,
 301                        vpbe_dev->current_timings.left_margin);
 302                osd_device->ops.set_top_margin(osd_device,
 303                vpbe_dev->current_timings.upper_margin);
 304                vpbe_dev->current_sd_index = sd_index;
 305                vpbe_dev->current_out_index = index;
 306        }
 307out:
 308        mutex_unlock(&vpbe_dev->lock);
 309        return ret;
 310}
 311
 312static int vpbe_set_default_output(struct vpbe_device *vpbe_dev)
 313{
 314        struct vpbe_config *cfg = vpbe_dev->cfg;
 315        int ret = 0;
 316        int i;
 317
 318        for (i = 0; i < cfg->num_outputs; i++) {
 319                if (!strcmp(def_output,
 320                            cfg->outputs[i].output.name)) {
 321                        ret = vpbe_set_output(vpbe_dev, i);
 322                        if (!ret)
 323                                vpbe_dev->current_out_index = i;
 324                        return ret;
 325                }
 326        }
 327        return ret;
 328}
 329
 330/**
 331 * vpbe_get_output - Get output
 332 * @vpbe_dev - vpbe device ptr
 333 *
 334 * return current vpbe output to the the index
 335 */
 336static unsigned int vpbe_get_output(struct vpbe_device *vpbe_dev)
 337{
 338        return vpbe_dev->current_out_index;
 339}
 340
 341/**
 342 * vpbe_s_dv_preset - Set the given preset timings in the encoder
 343 *
 344 * Sets the preset if supported by the current encoder. Return the status.
 345 * 0 - success & -EINVAL on error
 346 */
 347static int vpbe_s_dv_preset(struct vpbe_device *vpbe_dev,
 348                     struct v4l2_dv_preset *dv_preset)
 349{
 350        struct vpbe_config *cfg = vpbe_dev->cfg;
 351        int out_index = vpbe_dev->current_out_index;
 352        int sd_index = vpbe_dev->current_sd_index;
 353        int ret;
 354
 355
 356        if (!(cfg->outputs[out_index].output.capabilities &
 357            V4L2_OUT_CAP_PRESETS))
 358                return -EINVAL;
 359
 360        ret = vpbe_get_dv_preset_info(vpbe_dev, dv_preset->preset);
 361
 362        if (ret)
 363                return ret;
 364
 365        mutex_lock(&vpbe_dev->lock);
 366
 367
 368        ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
 369                                        s_dv_preset, dv_preset);
 370        /* set the lcd controller output for the given mode */
 371        if (!ret) {
 372                struct osd_state *osd_device = vpbe_dev->osd_device;
 373
 374                osd_device->ops.set_left_margin(osd_device,
 375                vpbe_dev->current_timings.left_margin);
 376                osd_device->ops.set_top_margin(osd_device,
 377                vpbe_dev->current_timings.upper_margin);
 378        }
 379        mutex_unlock(&vpbe_dev->lock);
 380
 381        return ret;
 382}
 383
 384/**
 385 * vpbe_g_dv_preset - Get the preset in the current encoder
 386 *
 387 * Get the preset in the current encoder. Return the status. 0 - success
 388 * -EINVAL on error
 389 */
 390static int vpbe_g_dv_preset(struct vpbe_device *vpbe_dev,
 391                     struct v4l2_dv_preset *dv_preset)
 392{
 393        if (vpbe_dev->current_timings.timings_type &
 394          VPBE_ENC_DV_PRESET) {
 395                dv_preset->preset = vpbe_dev->current_timings.timings.dv_preset;
 396                return 0;
 397        }
 398
 399        return -EINVAL;
 400}
 401
 402/**
 403 * vpbe_enum_dv_presets - Enumerate the dv presets in the current encoder
 404 *
 405 * Get the preset in the current encoder. Return the status. 0 - success
 406 * -EINVAL on error
 407 */
 408static int vpbe_enum_dv_presets(struct vpbe_device *vpbe_dev,
 409                         struct v4l2_dv_enum_preset *preset_info)
 410{
 411        struct vpbe_config *cfg = vpbe_dev->cfg;
 412        int out_index = vpbe_dev->current_out_index;
 413        struct vpbe_output *output = &cfg->outputs[out_index];
 414        int j = 0;
 415        int i;
 416
 417        if (!(output->output.capabilities & V4L2_OUT_CAP_PRESETS))
 418                return -EINVAL;
 419
 420        for (i = 0; i < output->num_modes; i++) {
 421                if (output->modes[i].timings_type == VPBE_ENC_DV_PRESET) {
 422                        if (j == preset_info->index)
 423                                break;
 424                        j++;
 425                }
 426        }
 427
 428        if (i == output->num_modes)
 429                return -EINVAL;
 430
 431        return v4l_fill_dv_preset_info(output->modes[i].timings.dv_preset,
 432                                        preset_info);
 433}
 434
 435/**
 436 * vpbe_s_std - Set the given standard in the encoder
 437 *
 438 * Sets the standard if supported by the current encoder. Return the status.
 439 * 0 - success & -EINVAL on error
 440 */
 441static int vpbe_s_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
 442{
 443        struct vpbe_config *cfg = vpbe_dev->cfg;
 444        int out_index = vpbe_dev->current_out_index;
 445        int sd_index = vpbe_dev->current_sd_index;
 446        int ret;
 447
 448        if (!(cfg->outputs[out_index].output.capabilities &
 449                V4L2_OUT_CAP_STD))
 450                return -EINVAL;
 451
 452        ret = vpbe_get_std_info(vpbe_dev, *std_id);
 453        if (ret)
 454                return ret;
 455
 456        mutex_lock(&vpbe_dev->lock);
 457
 458        ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
 459                               s_std_output, *std_id);
 460        /* set the lcd controller output for the given mode */
 461        if (!ret) {
 462                struct osd_state *osd_device = vpbe_dev->osd_device;
 463
 464                osd_device->ops.set_left_margin(osd_device,
 465                vpbe_dev->current_timings.left_margin);
 466                osd_device->ops.set_top_margin(osd_device,
 467                vpbe_dev->current_timings.upper_margin);
 468        }
 469        mutex_unlock(&vpbe_dev->lock);
 470
 471        return ret;
 472}
 473
 474/**
 475 * vpbe_g_std - Get the standard in the current encoder
 476 *
 477 * Get the standard in the current encoder. Return the status. 0 - success
 478 * -EINVAL on error
 479 */
 480static int vpbe_g_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
 481{
 482        struct vpbe_enc_mode_info cur_timings = vpbe_dev->current_timings;
 483
 484        if (cur_timings.timings_type & VPBE_ENC_STD) {
 485                *std_id = cur_timings.timings.std_id;
 486                return 0;
 487        }
 488
 489        return -EINVAL;
 490}
 491
 492/**
 493 * vpbe_set_mode - Set mode in the current encoder using mode info
 494 *
 495 * Use the mode string to decide what timings to set in the encoder
 496 * This is typically useful when fbset command is used to change the current
 497 * timings by specifying a string to indicate the timings.
 498 */
 499static int vpbe_set_mode(struct vpbe_device *vpbe_dev,
 500                         struct vpbe_enc_mode_info *mode_info)
 501{
 502        struct vpbe_enc_mode_info *preset_mode = NULL;
 503        struct vpbe_config *cfg = vpbe_dev->cfg;
 504        struct v4l2_dv_preset dv_preset;
 505        struct osd_state *osd_device;
 506        int out_index = vpbe_dev->current_out_index;
 507        int ret = 0;
 508        int i;
 509
 510        if ((NULL == mode_info) || (NULL == mode_info->name))
 511                return -EINVAL;
 512
 513        for (i = 0; i < cfg->outputs[out_index].num_modes; i++) {
 514                if (!strcmp(mode_info->name,
 515                     cfg->outputs[out_index].modes[i].name)) {
 516                        preset_mode = &cfg->outputs[out_index].modes[i];
 517                        /*
 518                         * it may be one of the 3 timings type. Check and
 519                         * invoke right API
 520                         */
 521                        if (preset_mode->timings_type & VPBE_ENC_STD)
 522                                return vpbe_s_std(vpbe_dev,
 523                                                 &preset_mode->timings.std_id);
 524                        if (preset_mode->timings_type & VPBE_ENC_DV_PRESET) {
 525                                dv_preset.preset =
 526                                        preset_mode->timings.dv_preset;
 527                                return vpbe_s_dv_preset(vpbe_dev, &dv_preset);
 528                        }
 529                }
 530        }
 531
 532        /* Only custom timing should reach here */
 533        if (preset_mode == NULL)
 534                return -EINVAL;
 535
 536        mutex_lock(&vpbe_dev->lock);
 537
 538        osd_device = vpbe_dev->osd_device;
 539        vpbe_dev->current_timings = *preset_mode;
 540        osd_device->ops.set_left_margin(osd_device,
 541                vpbe_dev->current_timings.left_margin);
 542        osd_device->ops.set_top_margin(osd_device,
 543                vpbe_dev->current_timings.upper_margin);
 544
 545        mutex_unlock(&vpbe_dev->lock);
 546
 547        return ret;
 548}
 549
 550static int vpbe_set_default_mode(struct vpbe_device *vpbe_dev)
 551{
 552        int ret;
 553
 554        ret = vpbe_get_std_info_by_name(vpbe_dev, def_mode);
 555        if (ret)
 556                return ret;
 557
 558        /* set the default mode in the encoder */
 559        return vpbe_set_mode(vpbe_dev, &vpbe_dev->current_timings);
 560}
 561
 562static int platform_device_get(struct device *dev, void *data)
 563{
 564        struct platform_device *pdev = to_platform_device(dev);
 565        struct vpbe_device *vpbe_dev = data;
 566
 567        if (strcmp("vpbe-osd", pdev->name) == 0)
 568                vpbe_dev->osd_device = platform_get_drvdata(pdev);
 569
 570        return 0;
 571}
 572
 573/**
 574 * vpbe_initialize() - Initialize the vpbe display controller
 575 * @vpbe_dev - vpbe device ptr
 576 *
 577 * Master frame buffer device drivers calls this to initialize vpbe
 578 * display controller. This will then registers v4l2 device and the sub
 579 * devices and sets a current encoder sub device for display. v4l2 display
 580 * device driver is the master and frame buffer display device driver is
 581 * the slave. Frame buffer display driver checks the initialized during
 582 * probe and exit if not initialized. Returns status.
 583 */
 584static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
 585{
 586        struct encoder_config_info *enc_info;
 587        struct v4l2_subdev **enc_subdev;
 588        struct osd_state *osd_device;
 589        struct i2c_adapter *i2c_adap;
 590        int output_index;
 591        int num_encoders;
 592        int ret = 0;
 593        int err;
 594        int i;
 595
 596        /*
 597         * v4l2 abd FBDev frame buffer devices will get the vpbe_dev pointer
 598         * from the platform device by iteration of platform drivers and
 599         * matching with device name
 600         */
 601        if (NULL == vpbe_dev || NULL == dev) {
 602                printk(KERN_ERR "Null device pointers.\n");
 603                return -ENODEV;
 604        }
 605
 606        if (vpbe_dev->initialized)
 607                return 0;
 608
 609        mutex_lock(&vpbe_dev->lock);
 610
 611        if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
 612                /* We have dac clock available for platform */
 613                vpbe_dev->dac_clk = clk_get(vpbe_dev->pdev, "vpss_dac");
 614                if (IS_ERR(vpbe_dev->dac_clk)) {
 615                        ret =  PTR_ERR(vpbe_dev->dac_clk);
 616                        goto vpbe_unlock;
 617                }
 618                if (clk_enable(vpbe_dev->dac_clk)) {
 619                        ret =  -ENODEV;
 620                        goto vpbe_unlock;
 621                }
 622        }
 623
 624        /* first enable vpss clocks */
 625        vpss_enable_clock(VPSS_VPBE_CLOCK, 1);
 626
 627        /* First register a v4l2 device */
 628        ret = v4l2_device_register(dev, &vpbe_dev->v4l2_dev);
 629        if (ret) {
 630                v4l2_err(dev->driver,
 631                        "Unable to register v4l2 device.\n");
 632                goto vpbe_fail_clock;
 633        }
 634        v4l2_info(&vpbe_dev->v4l2_dev, "vpbe v4l2 device registered\n");
 635
 636        err = bus_for_each_dev(&platform_bus_type, NULL, vpbe_dev,
 637                               platform_device_get);
 638        if (err < 0)
 639                return err;
 640
 641        vpbe_dev->venc = venc_sub_dev_init(&vpbe_dev->v4l2_dev,
 642                                           vpbe_dev->cfg->venc.module_name);
 643        /* register venc sub device */
 644        if (vpbe_dev->venc == NULL) {
 645                v4l2_err(&vpbe_dev->v4l2_dev,
 646                        "vpbe unable to init venc sub device\n");
 647                ret = -ENODEV;
 648                goto vpbe_fail_v4l2_device;
 649        }
 650        /* initialize osd device */
 651        osd_device = vpbe_dev->osd_device;
 652
 653        if (NULL != osd_device->ops.initialize) {
 654                err = osd_device->ops.initialize(osd_device);
 655                if (err) {
 656                        v4l2_err(&vpbe_dev->v4l2_dev,
 657                                 "unable to initialize the OSD device");
 658                        err = -ENOMEM;
 659                        goto vpbe_fail_v4l2_device;
 660                }
 661        }
 662
 663        /*
 664         * Register any external encoders that are configured. At index 0 we
 665         * store venc sd index.
 666         */
 667        num_encoders = vpbe_dev->cfg->num_ext_encoders + 1;
 668        vpbe_dev->encoders = kmalloc(
 669                                sizeof(struct v4l2_subdev *)*num_encoders,
 670                                GFP_KERNEL);
 671        if (NULL == vpbe_dev->encoders) {
 672                v4l2_err(&vpbe_dev->v4l2_dev,
 673                        "unable to allocate memory for encoders sub devices");
 674                ret = -ENOMEM;
 675                goto vpbe_fail_v4l2_device;
 676        }
 677
 678        i2c_adap = i2c_get_adapter(vpbe_dev->cfg->i2c_adapter_id);
 679        for (i = 0; i < (vpbe_dev->cfg->num_ext_encoders + 1); i++) {
 680                if (i == 0) {
 681                        /* venc is at index 0 */
 682                        enc_subdev = &vpbe_dev->encoders[i];
 683                        *enc_subdev = vpbe_dev->venc;
 684                        continue;
 685                }
 686                enc_info = &vpbe_dev->cfg->ext_encoders[i];
 687                if (enc_info->is_i2c) {
 688                        enc_subdev = &vpbe_dev->encoders[i];
 689                        *enc_subdev = v4l2_i2c_new_subdev_board(
 690                                                &vpbe_dev->v4l2_dev, i2c_adap,
 691                                                &enc_info->board_info, NULL);
 692                        if (*enc_subdev)
 693                                v4l2_info(&vpbe_dev->v4l2_dev,
 694                                          "v4l2 sub device %s registered\n",
 695                                          enc_info->module_name);
 696                        else {
 697                                v4l2_err(&vpbe_dev->v4l2_dev, "encoder %s"
 698                                         " failed to register",
 699                                         enc_info->module_name);
 700                                ret = -ENODEV;
 701                                goto vpbe_fail_sd_register;
 702                        }
 703                } else
 704                        v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders"
 705                                 " currently not supported");
 706        }
 707
 708        /* set the current encoder and output to that of venc by default */
 709        vpbe_dev->current_sd_index = 0;
 710        vpbe_dev->current_out_index = 0;
 711        output_index = 0;
 712
 713        mutex_unlock(&vpbe_dev->lock);
 714
 715        printk(KERN_NOTICE "Setting default output to %s\n", def_output);
 716        ret = vpbe_set_default_output(vpbe_dev);
 717        if (ret) {
 718                v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default output %s",
 719                         def_output);
 720                return ret;
 721        }
 722
 723        printk(KERN_NOTICE "Setting default mode to %s\n", def_mode);
 724        ret = vpbe_set_default_mode(vpbe_dev);
 725        if (ret) {
 726                v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default mode %s",
 727                         def_mode);
 728                return ret;
 729        }
 730        vpbe_dev->initialized = 1;
 731        /* TBD handling of bootargs for default output and mode */
 732        return 0;
 733
 734vpbe_fail_sd_register:
 735        kfree(vpbe_dev->encoders);
 736vpbe_fail_v4l2_device:
 737        v4l2_device_unregister(&vpbe_dev->v4l2_dev);
 738vpbe_fail_clock:
 739        if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0)
 740                clk_put(vpbe_dev->dac_clk);
 741vpbe_unlock:
 742        mutex_unlock(&vpbe_dev->lock);
 743        return ret;
 744}
 745
 746/**
 747 * vpbe_deinitialize() - de-initialize the vpbe display controller
 748 * @dev - Master and slave device ptr
 749 *
 750 * vpbe_master and slave frame buffer devices calls this to de-initialize
 751 * the display controller. It is called when master and slave device
 752 * driver modules are removed and no longer requires the display controller.
 753 */
 754static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev)
 755{
 756        v4l2_device_unregister(&vpbe_dev->v4l2_dev);
 757        if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0)
 758                clk_put(vpbe_dev->dac_clk);
 759
 760        kfree(vpbe_dev->encoders);
 761        vpbe_dev->initialized = 0;
 762        /* disable vpss clocks */
 763        vpss_enable_clock(VPSS_VPBE_CLOCK, 0);
 764}
 765
 766static struct vpbe_device_ops vpbe_dev_ops = {
 767        .g_cropcap = vpbe_g_cropcap,
 768        .enum_outputs = vpbe_enum_outputs,
 769        .set_output = vpbe_set_output,
 770        .get_output = vpbe_get_output,
 771        .s_dv_preset = vpbe_s_dv_preset,
 772        .g_dv_preset = vpbe_g_dv_preset,
 773        .enum_dv_presets = vpbe_enum_dv_presets,
 774        .s_std = vpbe_s_std,
 775        .g_std = vpbe_g_std,
 776        .initialize = vpbe_initialize,
 777        .deinitialize = vpbe_deinitialize,
 778        .get_mode_info = vpbe_get_current_mode_info,
 779        .set_mode = vpbe_set_mode,
 780};
 781
 782static __devinit int vpbe_probe(struct platform_device *pdev)
 783{
 784        struct vpbe_device *vpbe_dev;
 785        struct vpbe_config *cfg;
 786        int ret = -EINVAL;
 787
 788        if (pdev->dev.platform_data == NULL) {
 789                v4l2_err(pdev->dev.driver, "No platform data\n");
 790                return -ENODEV;
 791        }
 792        cfg = pdev->dev.platform_data;
 793
 794        if (!cfg->module_name[0] ||
 795            !cfg->osd.module_name[0] ||
 796            !cfg->venc.module_name[0]) {
 797                v4l2_err(pdev->dev.driver, "vpbe display module names not"
 798                         " defined\n");
 799                return ret;
 800        }
 801
 802        vpbe_dev = kzalloc(sizeof(*vpbe_dev), GFP_KERNEL);
 803        if (vpbe_dev == NULL) {
 804                v4l2_err(pdev->dev.driver, "Unable to allocate memory"
 805                         " for vpbe_device\n");
 806                return -ENOMEM;
 807        }
 808        vpbe_dev->cfg = cfg;
 809        vpbe_dev->ops = vpbe_dev_ops;
 810        vpbe_dev->pdev = &pdev->dev;
 811
 812        if (cfg->outputs->num_modes > 0)
 813                vpbe_dev->current_timings = vpbe_dev->cfg->outputs[0].modes[0];
 814        else
 815                return -ENODEV;
 816
 817        /* set the driver data in platform device */
 818        platform_set_drvdata(pdev, vpbe_dev);
 819        mutex_init(&vpbe_dev->lock);
 820
 821        return 0;
 822}
 823
 824static int vpbe_remove(struct platform_device *device)
 825{
 826        struct vpbe_device *vpbe_dev = platform_get_drvdata(device);
 827
 828        kfree(vpbe_dev);
 829
 830        return 0;
 831}
 832
 833static struct platform_driver vpbe_driver = {
 834        .driver = {
 835                .name   = "vpbe_controller",
 836                .owner  = THIS_MODULE,
 837        },
 838        .probe = vpbe_probe,
 839        .remove = vpbe_remove,
 840};
 841
 842/**
 843 * vpbe_init: initialize the vpbe driver
 844 *
 845 * This function registers device and driver to the kernel
 846 */
 847static __init int vpbe_init(void)
 848{
 849        return platform_driver_register(&vpbe_driver);
 850}
 851
 852/**
 853 * vpbe_cleanup : cleanup function for vpbe driver
 854 *
 855 * This will un-registers the device and driver to the kernel
 856 */
 857static void vpbe_cleanup(void)
 858{
 859        platform_driver_unregister(&vpbe_driver);
 860}
 861
 862/* Function for module initialization and cleanup */
 863module_init(vpbe_init);
 864module_exit(vpbe_cleanup);
 865
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.