linux/drivers/media/video/v4l2-common.c
<<
>>
Prefs
   1/*
   2 *      Video for Linux Two
   3 *
   4 *      A generic video device interface for the LINUX operating system
   5 *      using a set of device structures/vectors for low level operations.
   6 *
   7 *      This file replaces the videodev.c file that comes with the
   8 *      regular kernel distribution.
   9 *
  10 *      This program is free software; you can redistribute it and/or
  11 *      modify it under the terms of the GNU General Public License
  12 *      as published by the Free Software Foundation; either version
  13 *      2 of the License, or (at your option) any later version.
  14 *
  15 * Author:      Bill Dirks <bill@thedirks.org>
  16 *              based on code by Alan Cox, <alan@cymru.net>
  17 *
  18 */
  19
  20/*
  21 * Video capture interface for Linux
  22 *
  23 *      A generic video device interface for the LINUX operating system
  24 *      using a set of device structures/vectors for low level operations.
  25 *
  26 *              This program is free software; you can redistribute it and/or
  27 *              modify it under the terms of the GNU General Public License
  28 *              as published by the Free Software Foundation; either version
  29 *              2 of the License, or (at your option) any later version.
  30 *
  31 * Author:      Alan Cox, <alan@lxorguk.ukuu.org.uk>
  32 *
  33 * Fixes:
  34 */
  35
  36/*
  37 * Video4linux 1/2 integration by Justin Schoeman
  38 * <justin@suntiger.ee.up.ac.za>
  39 * 2.4 PROCFS support ported from 2.4 kernels by
  40 *  Iñaki García Etxebarria <garetxe@euskalnet.net>
  41 * Makefile fix by "W. Michael Petullo" <mike@flyn.org>
  42 * 2.4 devfs support ported from 2.4 kernels by
  43 *  Dan Merillat <dan@merillat.org>
  44 * Added Gerd Knorrs v4l1 enhancements (Justin Schoeman)
  45 */
  46
  47#include <linux/module.h>
  48#include <linux/types.h>
  49#include <linux/kernel.h>
  50#include <linux/mm.h>
  51#include <linux/string.h>
  52#include <linux/errno.h>
  53#include <linux/i2c.h>
  54#if defined(CONFIG_SPI)
  55#include <linux/spi/spi.h>
  56#endif
  57#include <asm/uaccess.h>
  58#include <asm/system.h>
  59#include <asm/pgtable.h>
  60#include <asm/io.h>
  61#include <asm/div64.h>
  62#include <media/v4l2-common.h>
  63#include <media/v4l2-device.h>
  64#include <media/v4l2-ctrls.h>
  65#include <media/v4l2-chip-ident.h>
  66
  67#include <linux/videodev2.h>
  68
  69MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
  70MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
  71MODULE_LICENSE("GPL");
  72
  73/*
  74 *
  75 *      V 4 L 2   D R I V E R   H E L P E R   A P I
  76 *
  77 */
  78
  79/*
  80 *  Video Standard Operations (contributed by Michael Schimek)
  81 */
  82
  83/* Helper functions for control handling                             */
  84
  85/* Check for correctness of the ctrl's value based on the data from
  86   struct v4l2_queryctrl and the available menu items. Note that
  87   menu_items may be NULL, in that case it is ignored. */
  88int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
  89                const char * const *menu_items)
  90{
  91        if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED)
  92                return -EINVAL;
  93        if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED)
  94                return -EBUSY;
  95        if (qctrl->type == V4L2_CTRL_TYPE_STRING)
  96                return 0;
  97        if (qctrl->type == V4L2_CTRL_TYPE_BUTTON ||
  98            qctrl->type == V4L2_CTRL_TYPE_INTEGER64 ||
  99            qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
 100                return 0;
 101        if (ctrl->value < qctrl->minimum || ctrl->value > qctrl->maximum)
 102                return -ERANGE;
 103        if (qctrl->type == V4L2_CTRL_TYPE_MENU && menu_items != NULL) {
 104                if (menu_items[ctrl->value] == NULL ||
 105                    menu_items[ctrl->value][0] == '\0')
 106                        return -EINVAL;
 107        }
 108        return 0;
 109}
 110EXPORT_SYMBOL(v4l2_ctrl_check);
 111
 112/* Fill in a struct v4l2_queryctrl */
 113int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
 114{
 115        const char *name;
 116
 117        v4l2_ctrl_fill(qctrl->id, &name, &qctrl->type,
 118                       &min, &max, &step, &def, &qctrl->flags);
 119
 120        if (name == NULL)
 121                return -EINVAL;
 122
 123        qctrl->minimum = min;
 124        qctrl->maximum = max;
 125        qctrl->step = step;
 126        qctrl->default_value = def;
 127        qctrl->reserved[0] = qctrl->reserved[1] = 0;
 128        strlcpy(qctrl->name, name, sizeof(qctrl->name));
 129        return 0;
 130}
 131EXPORT_SYMBOL(v4l2_ctrl_query_fill);
 132
 133/* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and
 134   the menu. The qctrl pointer may be NULL, in which case it is ignored.
 135   If menu_items is NULL, then the menu items are retrieved using
 136   v4l2_ctrl_get_menu. */
 137int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl,
 138               const char * const *menu_items)
 139{
 140        int i;
 141
 142        qmenu->reserved = 0;
 143        if (menu_items == NULL)
 144                menu_items = v4l2_ctrl_get_menu(qmenu->id);
 145        if (menu_items == NULL ||
 146            (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum)))
 147                return -EINVAL;
 148        for (i = 0; i < qmenu->index && menu_items[i]; i++) ;
 149        if (menu_items[i] == NULL || menu_items[i][0] == '\0')
 150                return -EINVAL;
 151        strlcpy(qmenu->name, menu_items[qmenu->index], sizeof(qmenu->name));
 152        return 0;
 153}
 154EXPORT_SYMBOL(v4l2_ctrl_query_menu);
 155
 156/* Fill in a struct v4l2_querymenu based on the specified array of valid
 157   menu items (terminated by V4L2_CTRL_MENU_IDS_END).
 158   Use this if there are 'holes' in the list of valid menu items. */
 159int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids)
 160{
 161        const char * const *menu_items = v4l2_ctrl_get_menu(qmenu->id);
 162
 163        qmenu->reserved = 0;
 164        if (menu_items == NULL || ids == NULL)
 165                return -EINVAL;
 166        while (*ids != V4L2_CTRL_MENU_IDS_END) {
 167                if (*ids++ == qmenu->index) {
 168                        strlcpy(qmenu->name, menu_items[qmenu->index],
 169                                        sizeof(qmenu->name));
 170                        return 0;
 171                }
 172        }
 173        return -EINVAL;
 174}
 175EXPORT_SYMBOL(v4l2_ctrl_query_menu_valid_items);
 176
 177/* ctrl_classes points to an array of u32 pointers, the last element is
 178   a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
 179   Each array must be sorted low to high and belong to the same control
 180   class. The array of u32 pointers must also be sorted, from low class IDs
 181   to high class IDs.
 182
 183   This function returns the first ID that follows after the given ID.
 184   When no more controls are available 0 is returned. */
 185u32 v4l2_ctrl_next(const u32 * const * ctrl_classes, u32 id)
 186{
 187        u32 ctrl_class = V4L2_CTRL_ID2CLASS(id);
 188        const u32 *pctrl;
 189
 190        if (ctrl_classes == NULL)
 191                return 0;
 192
 193        /* if no query is desired, then check if the ID is part of ctrl_classes */
 194        if ((id & V4L2_CTRL_FLAG_NEXT_CTRL) == 0) {
 195                /* find class */
 196                while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) != ctrl_class)
 197                        ctrl_classes++;
 198                if (*ctrl_classes == NULL)
 199                        return 0;
 200                pctrl = *ctrl_classes;
 201                /* find control ID */
 202                while (*pctrl && *pctrl != id) pctrl++;
 203                return *pctrl ? id : 0;
 204        }
 205        id &= V4L2_CTRL_ID_MASK;
 206        id++;   /* select next control */
 207        /* find first class that matches (or is greater than) the class of
 208           the ID */
 209        while (*ctrl_classes && V4L2_CTRL_ID2CLASS(**ctrl_classes) < ctrl_class)
 210                ctrl_classes++;
 211        /* no more classes */
 212        if (*ctrl_classes == NULL)
 213                return 0;
 214        pctrl = *ctrl_classes;
 215        /* find first ctrl within the class that is >= ID */
 216        while (*pctrl && *pctrl < id) pctrl++;
 217        if (*pctrl)
 218                return *pctrl;
 219        /* we are at the end of the controls of the current class. */
 220        /* continue with next class if available */
 221        ctrl_classes++;
 222        if (*ctrl_classes == NULL)
 223                return 0;
 224        return **ctrl_classes;
 225}
 226EXPORT_SYMBOL(v4l2_ctrl_next);
 227
 228int v4l2_chip_match_host(const struct v4l2_dbg_match *match)
 229{
 230        switch (match->type) {
 231        case V4L2_CHIP_MATCH_HOST:
 232                return match->addr == 0;
 233        default:
 234                return 0;
 235        }
 236}
 237EXPORT_SYMBOL(v4l2_chip_match_host);
 238
 239#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
 240int v4l2_chip_match_i2c_client(struct i2c_client *c, const struct v4l2_dbg_match *match)
 241{
 242        int len;
 243
 244        if (c == NULL || match == NULL)
 245                return 0;
 246
 247        switch (match->type) {
 248        case V4L2_CHIP_MATCH_I2C_DRIVER:
 249                if (c->driver == NULL || c->driver->driver.name == NULL)
 250                        return 0;
 251                len = strlen(c->driver->driver.name);
 252                /* legacy drivers have a ' suffix, don't try to match that */
 253                if (len && c->driver->driver.name[len - 1] == '\'')
 254                        len--;
 255                return len && !strncmp(c->driver->driver.name, match->name, len);
 256        case V4L2_CHIP_MATCH_I2C_ADDR:
 257                return c->addr == match->addr;
 258        default:
 259                return 0;
 260        }
 261}
 262EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
 263
 264int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_dbg_chip_ident *chip,
 265                u32 ident, u32 revision)
 266{
 267        if (!v4l2_chip_match_i2c_client(c, &chip->match))
 268                return 0;
 269        if (chip->ident == V4L2_IDENT_NONE) {
 270                chip->ident = ident;
 271                chip->revision = revision;
 272        }
 273        else {
 274                chip->ident = V4L2_IDENT_AMBIGUOUS;
 275                chip->revision = 0;
 276        }
 277        return 0;
 278}
 279EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
 280
 281/* ----------------------------------------------------------------- */
 282
 283/* I2C Helper functions */
 284
 285
 286void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
 287                const struct v4l2_subdev_ops *ops)
 288{
 289        v4l2_subdev_init(sd, ops);
 290        sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
 291        /* the owner is the same as the i2c_client's driver owner */
 292        sd->owner = client->driver->driver.owner;
 293        /* i2c_client and v4l2_subdev point to one another */
 294        v4l2_set_subdevdata(sd, client);
 295        i2c_set_clientdata(client, sd);
 296        /* initialize name */
 297        snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",
 298                client->driver->driver.name, i2c_adapter_id(client->adapter),
 299                client->addr);
 300}
 301EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
 302
 303
 304
 305/* Load an i2c sub-device. */
 306struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
 307                struct i2c_adapter *adapter, struct i2c_board_info *info,
 308                const unsigned short *probe_addrs)
 309{
 310        struct v4l2_subdev *sd = NULL;
 311        struct i2c_client *client;
 312
 313        BUG_ON(!v4l2_dev);
 314
 315        request_module(I2C_MODULE_PREFIX "%s", info->type);
 316
 317        /* Create the i2c client */
 318        if (info->addr == 0 && probe_addrs)
 319                client = i2c_new_probed_device(adapter, info, probe_addrs,
 320                                               NULL);
 321        else
 322                client = i2c_new_device(adapter, info);
 323
 324        /* Note: by loading the module first we are certain that c->driver
 325           will be set if the driver was found. If the module was not loaded
 326           first, then the i2c core tries to delay-load the module for us,
 327           and then c->driver is still NULL until the module is finally
 328           loaded. This delay-load mechanism doesn't work if other drivers
 329           want to use the i2c device, so explicitly loading the module
 330           is the best alternative. */
 331        if (client == NULL || client->driver == NULL)
 332                goto error;
 333
 334        /* Lock the module so we can safely get the v4l2_subdev pointer */
 335        if (!try_module_get(client->driver->driver.owner))
 336                goto error;
 337        sd = i2c_get_clientdata(client);
 338
 339        /* Register with the v4l2_device which increases the module's
 340           use count as well. */
 341        if (v4l2_device_register_subdev(v4l2_dev, sd))
 342                sd = NULL;
 343        /* Decrease the module use count to match the first try_module_get. */
 344        module_put(client->driver->driver.owner);
 345
 346error:
 347        /* If we have a client but no subdev, then something went wrong and
 348           we must unregister the client. */
 349        if (client && sd == NULL)
 350                i2c_unregister_device(client);
 351        return sd;
 352}
 353EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
 354
 355struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
 356                struct i2c_adapter *adapter, const char *client_type,
 357                u8 addr, const unsigned short *probe_addrs)
 358{
 359        struct i2c_board_info info;
 360
 361        /* Setup the i2c board info with the device type and
 362           the device address. */
 363        memset(&info, 0, sizeof(info));
 364        strlcpy(info.type, client_type, sizeof(info.type));
 365        info.addr = addr;
 366
 367        return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs);
 368}
 369EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
 370
 371/* Return i2c client address of v4l2_subdev. */
 372unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
 373{
 374        struct i2c_client *client = v4l2_get_subdevdata(sd);
 375
 376        return client ? client->addr : I2C_CLIENT_END;
 377}
 378EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_addr);
 379
 380/* Return a list of I2C tuner addresses to probe. Use only if the tuner
 381   addresses are unknown. */
 382const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
 383{
 384        static const unsigned short radio_addrs[] = {
 385#if defined(CONFIG_MEDIA_TUNER_TEA5761) || defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE)
 386                0x10,
 387#endif
 388                0x60,
 389                I2C_CLIENT_END
 390        };
 391        static const unsigned short demod_addrs[] = {
 392                0x42, 0x43, 0x4a, 0x4b,
 393                I2C_CLIENT_END
 394        };
 395        static const unsigned short tv_addrs[] = {
 396                0x42, 0x43, 0x4a, 0x4b,         /* tda8290 */
 397                0x60, 0x61, 0x62, 0x63, 0x64,
 398                I2C_CLIENT_END
 399        };
 400
 401        switch (type) {
 402        case ADDRS_RADIO:
 403                return radio_addrs;
 404        case ADDRS_DEMOD:
 405                return demod_addrs;
 406        case ADDRS_TV:
 407                return tv_addrs;
 408        case ADDRS_TV_WITH_DEMOD:
 409                return tv_addrs + 4;
 410        }
 411        return NULL;
 412}
 413EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
 414
 415#endif /* defined(CONFIG_I2C) */
 416
 417#if defined(CONFIG_SPI)
 418
 419/* Load a spi sub-device. */
 420
 421void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
 422                const struct v4l2_subdev_ops *ops)
 423{
 424        v4l2_subdev_init(sd, ops);
 425        sd->flags |= V4L2_SUBDEV_FL_IS_SPI;
 426        /* the owner is the same as the spi_device's driver owner */
 427        sd->owner = spi->dev.driver->owner;
 428        /* spi_device and v4l2_subdev point to one another */
 429        v4l2_set_subdevdata(sd, spi);
 430        spi_set_drvdata(spi, sd);
 431        /* initialize name */
 432        strlcpy(sd->name, spi->dev.driver->name, sizeof(sd->name));
 433}
 434EXPORT_SYMBOL_GPL(v4l2_spi_subdev_init);
 435
 436struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
 437                struct spi_master *master, struct spi_board_info *info)
 438{
 439        struct v4l2_subdev *sd = NULL;
 440        struct spi_device *spi = NULL;
 441
 442        BUG_ON(!v4l2_dev);
 443
 444        if (info->modalias)
 445                request_module(info->modalias);
 446
 447        spi = spi_new_device(master, info);
 448
 449        if (spi == NULL || spi->dev.driver == NULL)
 450                goto error;
 451
 452        if (!try_module_get(spi->dev.driver->owner))
 453                goto error;
 454
 455        sd = spi_get_drvdata(spi);
 456
 457        /* Register with the v4l2_device which increases the module's
 458           use count as well. */
 459        if (v4l2_device_register_subdev(v4l2_dev, sd))
 460                sd = NULL;
 461
 462        /* Decrease the module use count to match the first try_module_get. */
 463        module_put(spi->dev.driver->owner);
 464
 465error:
 466        /* If we have a client but no subdev, then something went wrong and
 467           we must unregister the client. */
 468        if (spi && sd == NULL)
 469                spi_unregister_device(spi);
 470
 471        return sd;
 472}
 473EXPORT_SYMBOL_GPL(v4l2_spi_new_subdev);
 474
 475#endif /* defined(CONFIG_SPI) */
 476
 477/* Clamp x to be between min and max, aligned to a multiple of 2^align.  min
 478 * and max don't have to be aligned, but there must be at least one valid
 479 * value.  E.g., min=17,max=31,align=4 is not allowed as there are no multiples
 480 * of 16 between 17 and 31.  */
 481static unsigned int clamp_align(unsigned int x, unsigned int min,
 482                                unsigned int max, unsigned int align)
 483{
 484        /* Bits that must be zero to be aligned */
 485        unsigned int mask = ~((1 << align) - 1);
 486
 487        /* Round to nearest aligned value */
 488        if (align)
 489                x = (x + (1 << (align - 1))) & mask;
 490
 491        /* Clamp to aligned value of min and max */
 492        if (x < min)
 493                x = (min + ~mask) & mask;
 494        else if (x > max)
 495                x = max & mask;
 496
 497        return x;
 498}
 499
 500/* Bound an image to have a width between wmin and wmax, and height between
 501 * hmin and hmax, inclusive.  Additionally, the width will be a multiple of
 502 * 2^walign, the height will be a multiple of 2^halign, and the overall size
 503 * (width*height) will be a multiple of 2^salign.  The image may be shrunk
 504 * or enlarged to fit the alignment constraints.
 505 *
 506 * The width or height maximum must not be smaller than the corresponding
 507 * minimum.  The alignments must not be so high there are no possible image
 508 * sizes within the allowed bounds.  wmin and hmin must be at least 1
 509 * (don't use 0).  If you don't care about a certain alignment, specify 0,
 510 * as 2^0 is 1 and one byte alignment is equivalent to no alignment.  If
 511 * you only want to adjust downward, specify a maximum that's the same as
 512 * the initial value.
 513 */
 514void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
 515                           unsigned int walign,
 516                           u32 *h, unsigned int hmin, unsigned int hmax,
 517                           unsigned int halign, unsigned int salign)
 518{
 519        *w = clamp_align(*w, wmin, wmax, walign);
 520        *h = clamp_align(*h, hmin, hmax, halign);
 521
 522        /* Usually we don't need to align the size and are done now. */
 523        if (!salign)
 524                return;
 525
 526        /* How much alignment do we have? */
 527        walign = __ffs(*w);
 528        halign = __ffs(*h);
 529        /* Enough to satisfy the image alignment? */
 530        if (walign + halign < salign) {
 531                /* Max walign where there is still a valid width */
 532                unsigned int wmaxa = __fls(wmax ^ (wmin - 1));
 533                /* Max halign where there is still a valid height */
 534                unsigned int hmaxa = __fls(hmax ^ (hmin - 1));
 535
 536                /* up the smaller alignment until we have enough */
 537                do {
 538                        if (halign >= hmaxa ||
 539                            (walign <= halign && walign < wmaxa)) {
 540                                *w = clamp_align(*w, wmin, wmax, walign + 1);
 541                                walign = __ffs(*w);
 542                        } else {
 543                                *h = clamp_align(*h, hmin, hmax, halign + 1);
 544                                halign = __ffs(*h);
 545                        }
 546                } while (halign + walign < salign);
 547        }
 548}
 549EXPORT_SYMBOL_GPL(v4l_bound_align_image);
 550
 551/**
 552 * v4l_fill_dv_preset_info - fill description of a digital video preset
 553 * @preset - preset value
 554 * @info - pointer to struct v4l2_dv_enum_preset
 555 *
 556 * drivers can use this helper function to fill description of dv preset
 557 * in info.
 558 */
 559int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info)
 560{
 561        static const struct v4l2_dv_preset_info {
 562                u16 width;
 563                u16 height;
 564                const char *name;
 565        } dv_presets[] = {
 566                { 0, 0, "Invalid" },            /* V4L2_DV_INVALID */
 567                { 720,  480, "480p@59.94" },    /* V4L2_DV_480P59_94 */
 568                { 720,  576, "576p@50" },       /* V4L2_DV_576P50 */
 569                { 1280, 720, "720p@24" },       /* V4L2_DV_720P24 */
 570                { 1280, 720, "720p@25" },       /* V4L2_DV_720P25 */
 571                { 1280, 720, "720p@30" },       /* V4L2_DV_720P30 */
 572                { 1280, 720, "720p@50" },       /* V4L2_DV_720P50 */
 573                { 1280, 720, "720p@59.94" },    /* V4L2_DV_720P59_94 */
 574                { 1280, 720, "720p@60" },       /* V4L2_DV_720P60 */
 575                { 1920, 1080, "1080i@29.97" },  /* V4L2_DV_1080I29_97 */
 576                { 1920, 1080, "1080i@30" },     /* V4L2_DV_1080I30 */
 577                { 1920, 1080, "1080i@25" },     /* V4L2_DV_1080I25 */
 578                { 1920, 1080, "1080i@50" },     /* V4L2_DV_1080I50 */
 579                { 1920, 1080, "1080i@60" },     /* V4L2_DV_1080I60 */
 580                { 1920, 1080, "1080p@24" },     /* V4L2_DV_1080P24 */
 581                { 1920, 1080, "1080p@25" },     /* V4L2_DV_1080P25 */
 582                { 1920, 1080, "1080p@30" },     /* V4L2_DV_1080P30 */
 583                { 1920, 1080, "1080p@50" },     /* V4L2_DV_1080P50 */
 584                { 1920, 1080, "1080p@60" },     /* V4L2_DV_1080P60 */
 585        };
 586
 587        if (info == NULL || preset >= ARRAY_SIZE(dv_presets))
 588                return -EINVAL;
 589
 590        info->preset = preset;
 591        info->width = dv_presets[preset].width;
 592        info->height = dv_presets[preset].height;
 593        strlcpy(info->name, dv_presets[preset].name, sizeof(info->name));
 594        return 0;
 595}
 596EXPORT_SYMBOL_GPL(v4l_fill_dv_preset_info);
 597
 598const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
 599                const struct v4l2_discrete_probe *probe,
 600                s32 width, s32 height)
 601{
 602        int i;
 603        u32 error, min_error = UINT_MAX;
 604        const struct v4l2_frmsize_discrete *size, *best = NULL;
 605
 606        if (!probe)
 607                return best;
 608
 609        for (i = 0, size = probe->sizes; i < probe->num_sizes; i++, size++) {
 610                error = abs(size->width - width) + abs(size->height - height);
 611                if (error < min_error) {
 612                        min_error = error;
 613                        best = size;
 614                }
 615                if (!error)
 616                        break;
 617        }
 618
 619        return best;
 620}
 621EXPORT_SYMBOL_GPL(v4l2_find_nearest_format);
 622