1 /* $NetBSD: pickmode.c,v 1.2 2010/10/12 16:18:19 macallan Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 The NetBSD Foundation 5 * All rights reserved. 6 * 7 * this code was contributed to The NetBSD Foundation by Michael Lorenz 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS 19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE NETBSD FOUNDATION BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: pickmode.c,v 1.2 2010/10/12 16:18:19 macallan Exp $"); 33 34 #include <sys/param.h> 35 #include <dev/videomode/videomode.h> 36 #include "opt_videomode.h" 37 38 #ifdef PICKMODE_DEBUG 39 #define DPRINTF printf 40 #else 41 #define DPRINTF while (0) printf 42 #endif 43 44 const struct videomode * 45 pick_mode_by_dotclock(int width, int height, int dotclock) 46 { 47 const struct videomode *this, *best = NULL; 48 int i; 49 50 DPRINTF("%s: looking for %d x %d at up to %d kHz\n", __func__, width, 51 height, dotclock); 52 for (i = 0; i < videomode_count; i++) { 53 54 this = &videomode_list[i]; 55 if ((this->hdisplay != width) || (this->vdisplay != height) || 56 (this->dot_clock > dotclock)) 57 continue; 58 if (best != NULL) { 59 60 if (this->dot_clock > best->dot_clock) 61 best = this; 62 } else 63 best = this; 64 } 65 if (best!= NULL) 66 DPRINTF("found %s\n", best->name); 67 68 return best; 69 } 70 71 const struct videomode * 72 pick_mode_by_ref(int width, int height, int refresh) 73 { 74 const struct videomode *this, *best = NULL; 75 int mref, closest = 1000, i, diff; 76 77 DPRINTF("%s: looking for %d x %d at up to %d Hz\n", __func__, width, 78 height, refresh); 79 for (i = 0; i < videomode_count; i++) { 80 81 this = &videomode_list[i]; 82 mref = this->dot_clock * 1000 / (this->htotal * this->vtotal); 83 diff = abs(mref - refresh); 84 if ((this->hdisplay != width) || (this->vdisplay != height)) 85 continue; 86 DPRINTF("%s in %d hz, diff %d\n", this->name, mref, diff); 87 if (best != NULL) { 88 89 if (diff < closest) { 90 91 best = this; 92 closest = diff; 93 } 94 } else { 95 best = this; 96 closest = diff; 97 } 98 } 99 if (best!= NULL) 100 DPRINTF("found %s %d\n", best->name, best->dot_clock); 101 102 return best; 103 } 104