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