diff -Nru nvclock-0.8b3/ChangeLog nvclock-0.8b4/ChangeLog --- nvclock-0.8b3/ChangeLog 2008-01-04 17:32:07.000000000 +0000 +++ nvclock-0.8b4/ChangeLog 2009-01-04 15:18:45.000000000 +0000 @@ -1,6 +1,20 @@ Revision History: ================= +v0.8b4 - January, 4, 2009 +------------------------- + + o Initial GT200 support + o Smartdimmer support for various Geforce8/9 laptops from Sony, Samsung, HP and Apple + o Added an smartdimmer program to replace the original smartdimmer 0.1 program by Erik Wahling + o Bios dumping using PRAMIN to prevent flickering + o Bios parsing fixes for newer Geforce9/GT200 bioses + o Fanspeed adjustment on various Geforce8/9/GT200 cards + o Use of video bios sensor calibration data on Geforce6-GT200 cards + o Improved support for internal GPU diode temperature on G84/G86/G94/G96 cards + o Fixed NV-CONTROL crash in nvclock_gtk + o Many small bugfixes + v0.8b3 - January, 4, 2008 ------------------------- diff -Nru nvclock-0.8b3/Makefile.in nvclock-0.8b4/Makefile.in --- nvclock-0.8b3/Makefile.in 2005-05-28 14:11:35.000000000 +0000 +++ nvclock-0.8b4/Makefile.in 2008-05-11 10:25:44.000000000 +0000 @@ -1,6 +1,6 @@ INSTALL=@INSTALL@ -prefix=@prefix@ +prefix=$(DESTDIR)@prefix@ docdir=${prefix}/share/doc/nvclock mandir=${prefix}/man DOCS= ABOUT AUTHORS ChangeLog FAQ README @@ -15,7 +15,7 @@ $(MAKE) -C src distclean rm -f *.h config.log config.cache config.status Makefile stamp-h -install: install-docs install-man +install: install-docs install-man install-desktop-shortcut $(MAKE) -C src install install-docs: @@ -29,11 +29,17 @@ echo "installing $$doc as $$dir/$$name"; \ done +install-desktop-shortcut: + mkdir -p $(prefix)/share/applications + mkdir -p $(prefix)/share/icons/hicolor/48x48/apps + cp nvclock.desktop $(prefix)/share/applications + cp nvclock.png $(prefix)/share/icons/hicolor/48x48/apps + install-man: mkdir -p $(mandir)/man1 cp nvclock.1 $(mandir)/man1 -uninstall: uninstall-docs uninstall-man +uninstall: uninstall-docs uninstall-man uninstall-desktop-shortcut $(MAKE) -C src uninstall uninstall-docs: @@ -46,6 +52,12 @@ echo "removing $$dir/$$name" ; \ done +uninstall-desktop-shortcut: + rm -f $(prefix)/share/applications/nvclock.desktop + echo "removing $$prefix/share/applications/nvclock.desktop" ; \ + rm -f $(prefix)/share/icons/hicolor/48x48/apps/nvclock.png + echo "removing $$prefix/share/icons/hicolor/48x48/apps/nvclock.png" ; \ + uninstall-man: rm -f $(mandir)/man1/nvclock.1 echo "removing $$mandir/man1/nvclock.1" ; \ diff -Nru nvclock-0.8b3/README nvclock-0.8b4/README --- nvclock-0.8b3/README 2008-01-04 17:34:13.000000000 +0000 +++ nvclock-0.8b4/README 2009-01-03 17:10:56.000000000 +0000 @@ -1,4 +1,4 @@ -NVClock Version 0.8 (Beta3) +NVClock Version 0.8 (Beta4) site: http://nvclock.sourceforge.net @@ -93,6 +93,19 @@ at frequencies higher than 300 MHz you might notice that overclocking goes in steps of 6-7 MHz or sometimes even 13-14MHz. On GeforceFX/Geforce6 cards the situation is normal again. +As of 0.8b4 NVClock also ships with a program called smartdimmer which can be used on laptops to tune +the backlight. This program works on various Geforce6/7 laptops from Sony and Geforce8/9 laptops from +Sony, Samsung, HP, Apple and Zepto. + +Usage: ./smartdimmer [options] + +Options: + -g --get Query brightness level. + -s --set Set brightness level (15-100) + -i --increase Increase brightness with one level. + -d --decrease Decrease brightness with one level. + -h --help Prints this help text. + Acknowledgments =============== @@ -103,7 +116,8 @@ o Jan Prokop for creating a qt version o NVIDIA, for having good Linux drivers o Ashley from EntechTaiwan for helping me a bit. - o levon, Dragoran, chr-, etorix, Kano, kelmo, ddl, w00ter, dopez and all others (from #nvidia/#nvclock/#kanotix) + o Lipp Moritz (neldoreth) for a lot of testing of 0.8b4 + o levon, Dragoran, chr-, etorix, Kano, kelmo, Daenjo, ddl, w00ter, dopez and all others (from #nvidia/#nvclock/#kanotix) o Alexey Nicolaychuk (Unwinder) Plans for the future diff -Nru nvclock-0.8b3/acinclude.m4 nvclock-0.8b4/acinclude.m4 --- nvclock-0.8b3/acinclude.m4 2005-08-13 21:12:18.000000000 +0000 +++ nvclock-0.8b4/acinclude.m4 2008-05-11 10:25:45.000000000 +0000 @@ -113,12 +113,13 @@ #Try to find the qt libs in /usr/lib and /usr/local/lib for i in $QT_LIB_SEARCH; do - if test "x`ls $i/libqt.* 2> /dev/null`" != x ; then + if test "x`ls $i/libqt* 2> /dev/null`" != x ; then QT_LIB_DIR=$i fi done fi - +echo $QT_LIB_DIR +echo $QT_INC_DIR if test x"$QT_INC_DIR" = x -o x"$QT_LIB_DIR" = x; then echo "*** Can't find qt header/library directories, you can fix this using two ways depending on your system:" echo "*** - set QTDIR or use -with-qtdir=DIR option" diff -Nru nvclock-0.8b3/configure.in nvclock-0.8b4/configure.in --- nvclock-0.8b3/configure.in 2007-12-02 21:30:17.000000000 +0000 +++ nvclock-0.8b4/configure.in 2008-08-16 16:53:54.000000000 +0000 @@ -103,30 +103,17 @@ fi if test x"$enable_nvcontrol" = "xyes"; then - PKG_CHECK_MODULES([X11], [x11], , [AC_PATH_XTRA]) - if test x$no_x = x ; then - if test x$x_libraries = x ; then - X11_LIBS= - AC_CHECK_LIB(X11, XOpenDisplay) - AC_CHECK_LIB(Xext, XextFindDisplay,,, -lXext) - HAVE_NVCONTROL=yes - else - AC_CHECK_LIB(X11, XOpenDisplay,,, -L$x_libraries) - AC_CHECK_LIB(Xext, XextFindDisplay,,, -L$x_libraries -lXext) - HAVE_NVCONTROL=yes - fi - else - AC_MSG_NOTICE([no X Window System found]) - HAVE_NVCONTROL=no - fi - - if test x"$HAVE_NVCONTROL" = "xyes" ; then - X11_CFLAGS=$X_CFLAGS - X11_LIBS="$X_LIBS $LIBS" + PKG_CHECK_MODULES([X11], [x11], , AC_MSG_ERROR("X11 required for nvcontrol support")) + PKG_CHECK_MODULES([XEXT], [xext], , AC_MSG_ERROR("Xext required for nvcontrol support")) + + X11_CFLAGS="$X11_CFLAGS $XEXT_CFLAGS" + X11_LIBS="$X11_LIBS $XEXT_LIBS" + if test x"$X11_LIBS" != x ; then + HAVE_NVCONTROL=yes AC_SUBST(X11_CFLAGS) - AC_SUBST(X11_LIBS) + AC_SUBST(X11_LIBS) AC_DEFINE([HAVE_NVCONTROL], [1], [NV-CONTROL support for changing OpenGL settings]) - fi + fi fi AC_SUBST(HAVE_GTK2) diff -Nru nvclock-0.8b3/debian/changelog nvclock-0.8b4/debian/changelog --- nvclock-0.8b3/debian/changelog 2009-03-20 23:34:16.000000000 +0000 +++ nvclock-0.8b4/debian/changelog 2009-03-20 23:34:16.000000000 +0000 @@ -1,3 +1,26 @@ +nvclock (0.8b4-1ubuntu1) jaunty; urgency=low + + * Merge from Debian unstable, remaining changes: + - Add dpatch back to build-depends. + - Update 01_fix_buffer_overflow dpatch. + * lintian fixes: + - debian/copyright: add an actual copyright notice. + - debian/copyright: copy the GPLv2+ license text. + - remove empty debian/nvclock.postinst - minor, but makes dpkg less + efficient about package states + - debian/control: GTK -> GTK+ + - debian/nvclock-{qt,gtk}.menu: quote the "needs" and "section" + strings, and use the menu section that the Debian menu policy + explicitly says this package should be using (System/Hardware) :-) + + -- Steve Langasek Fri, 20 Mar 2009 22:58:10 +0000 + +nvclock (0.8b4-1) unstable; urgency=low + + * New upstream release. (closes: #511979, #433375, #360097, #414236) + + -- Randall Donald Fri, 20 Feb 2009 12:02:17 -0800 + nvclock (0.8b3-1ubuntu1) hardy; urgency=low * Merge from debian unstable, remaining changes: diff -Nru nvclock-0.8b3/debian/control nvclock-0.8b4/debian/control --- nvclock-0.8b3/debian/control 2009-03-20 23:34:16.000000000 +0000 +++ nvclock-0.8b4/debian/control 2009-03-20 23:34:16.000000000 +0000 @@ -26,7 +26,7 @@ The official binary nVidia drivers are required for accesses other than by root. . - This is the GTK version. + This is the GTK+ version. Package: nvclock-qt Architecture: any diff -Nru nvclock-0.8b3/debian/copyright nvclock-0.8b4/debian/copyright --- nvclock-0.8b3/debian/copyright 2009-03-20 23:34:16.000000000 +0000 +++ nvclock-0.8b4/debian/copyright 2009-03-20 23:34:16.000000000 +0000 @@ -9,6 +9,12 @@ Christian Zander Jan Prokop -You are free to distribute this software under the terms of the GNU General -Public License. On Debian systems, the complete text of the GNU General Public +Copyright 2001-2008 Roderick Colenbrander et al. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL file. diff -Nru nvclock-0.8b3/debian/nvclock-gtk.menu nvclock-0.8b4/debian/nvclock-gtk.menu --- nvclock-0.8b3/debian/nvclock-gtk.menu 2009-03-20 23:34:16.000000000 +0000 +++ nvclock-0.8b4/debian/nvclock-gtk.menu 2009-03-20 23:34:16.000000000 +0000 @@ -1,6 +1,6 @@ ?package(nvclock-gtk):\ - needs=X11\ - section=Apps/System\ + needs="X11"\ + section="Applications/System/Hardware"\ longtitle="nvclock: overclock your nVidia card (GTK GUI)"\ title="Nvclock for GTK+"\ command="/usr/bin/nvclock_gtk" diff -Nru nvclock-0.8b3/debian/nvclock-qt.menu nvclock-0.8b4/debian/nvclock-qt.menu --- nvclock-0.8b3/debian/nvclock-qt.menu 2009-03-20 23:34:16.000000000 +0000 +++ nvclock-0.8b4/debian/nvclock-qt.menu 2009-03-20 23:34:16.000000000 +0000 @@ -1,6 +1,6 @@ ?package(nvclock-qt):\ - needs=X11\ - section=Apps/System\ + needs="X11"\ + section="Applications/System/Hardware"\ longtitle="nvclock: overclock your nVidia card (Qt GUI)"\ title="Nvclock for Qt"\ command="/usr/bin/nvclock_qt" diff -Nru nvclock-0.8b3/debian/nvclock.postinst nvclock-0.8b4/debian/nvclock.postinst --- nvclock-0.8b3/debian/nvclock.postinst 2009-03-20 23:34:16.000000000 +0000 +++ nvclock-0.8b4/debian/nvclock.postinst 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -#!/bin/sh -# postinst script for nvclock -# -# Mostly stolen from the Debian xdm scripts -# Copyright 1998, 1999 Branden Robinson. Licensed under the GNU GPL. -# Acknowlegements to Stephen Early, Mark Eichin, and Manoj Srivastava. -# -# see: dh_installdeb(1) - -set -e -#. /usr/share/debconf/confmodule -# db_version 2.0 - -case "$1" in - configure) - ;; - abort-upgrade|abort-remove|abort-deconfigure) - ;; - - *) - echo "postinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 diff -Nru nvclock-0.8b3/nvclock.desktop nvclock-0.8b4/nvclock.desktop --- nvclock-0.8b3/nvclock.desktop 1970-01-01 00:00:00.000000000 +0000 +++ nvclock-0.8b4/nvclock.desktop 2008-01-06 13:28:26.000000000 +0000 @@ -0,0 +1,9 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=NVCLOCK +Comment=Overclock and Monitor NVIDIA cards +Exec=nvclock_gtk +Icon=nvclock.png +Terminal=false +Type=Application +Categories=System; Binary files /tmp/mmf3nXF2Mt/nvclock-0.8b3/nvclock.png and /tmp/7EUOMN8pg1/nvclock-0.8b4/nvclock.png differ diff -Nru nvclock-0.8b3/src/Makefile.in nvclock-0.8b4/src/Makefile.in --- nvclock-0.8b3/src/Makefile.in 2005-09-02 08:56:03.000000000 +0000 +++ nvclock-0.8b4/src/Makefile.in 2009-01-03 17:02:54.000000000 +0000 @@ -1,15 +1,16 @@ CC=@CC@ INSTALL=@INSTALL@ -SOURCES=nvclock.c +nvclock_SOURCES=nvclock.c +smartdimmer_SOURCES=smartdimmer.c SUBDIRS=backend nvcontrol gtk qt HAVE_NVCONTROL=@HAVE_NVCONTROL@ libbackend=./backend/libbackend.a libnvcontrol=./nvcontrol/libnvcontrol.a -prefix=@prefix@ -exec_prefix=@exec_prefix@ -bindir=@bindir@ +prefix=$(DESTDIR)@prefix@ +exec_prefix=$(DESTDIR)@exec_prefix@ +bindir=$(DESTDIR)@bindir@ ifeq ($(HAVE_NVCONTROL), yes) DEPS=$(libbackend) $(libnvcontrol) @@ -26,16 +27,20 @@ distclean install install-app install-recursive -all: all-recursive nvclock +all: all-recursive nvclock smartdimmer nvclock: $(DEPS) $(LIB) nvclock.c - $(CC) -o nvclock $(SOURCES) $(INCLUDES) $(LIBS) + $(CC) -o nvclock $(nvclock_SOURCES) $(INCLUDES) $(LIBS) + +smartdimmer: $(DEPS) $(LIB) smartdimmer.c + $(CC) -o smartdimmer $(smartdimmer_SOURCES) $(INCLUDES) $(LIBS) clean: clean-recursive clean-app clean-app: rm -f nvclock *.exe + rm -f smartdimmer distclean: distclean-recursive clean-app @@ -45,12 +50,13 @@ install: install-recursive install-app install-app: mkdir -p $(bindir) - $(INSTALL) -c nvclock $(bindir)/nvclock + $(INSTALL) -c nvclock $(DESTDIR)$(bindir)/nvclock + $(INSTALL) -c smartdimmer $(DESTDIR)$(bindir)/smartdimmer uninstall: uninstall-recursive uninstall-app uninstall-app: - rm -f $(bindir)/nvclock + rm -f $(bindir)/smartdimmer # Walk through the sub directories and do what is requested diff -Nru nvclock-0.8b3/src/backend/adt7473.c nvclock-0.8b4/src/backend/adt7473.c --- nvclock-0.8b3/src/backend/adt7473.c 2007-11-02 10:23:00.000000000 +0000 +++ nvclock-0.8b4/src/backend/adt7473.c 2008-12-21 16:10:45.000000000 +0000 @@ -84,18 +84,30 @@ I2CByte cfg; int offset = 0; - /* We add a 10C offset to the temperature though this isn't conform - / the ADT7473 datasheet. The reason we add this is to show a temperature - / similar to the internal gpu sensor. Right now the board and gpu - / temperature as reported by the sensor are about the same (there's - / a difference between the two or 3-4C). Most likely the internal gpu - / temperature is a bit higher and assuming the temperature as reported - / by the internal sensor is correct adding a 10C offset is a good solution. - / (The offset seems to be the same independant of the temperature which) - / Don't do it on NV50, it doesn't have an internal sensor? + /* The temperature needs to be corrected using an offset which is stored in the bios. + / If no bios has been parsed we fall back to a default value. */ - if(dev->arch & NV4X) - offset = 10; + if(nv_card->bios) + { + offset = nv_card->bios->sensor_cfg.temp_correction; + } + else + { + /* We add a 10C offset to the temperature though this isn't conform + / the ADT7473 datasheet. The reason we add this is to show a temperature + / similar to the internal gpu sensor. Right now the board and gpu + / temperature as reported by the sensor are about the same (there's + / a difference between the two or 3-4C). Most likely the internal gpu + / temperature is a bit higher and assuming the temperature as reported + / by the internal sensor is correct adding a 10C offset is a good solution. + / Add an offset of 8C for 8*00/GTX2*0 cards but it doesn't seem 100% correct though. + / It could be that +7C is more correct for 8800GT cards. + */ + if(dev->arch & NV4X) + offset = 10; + else if(dev->arch & NV5X) + offset = 8; + } xf86I2CReadByte(dev, ADT7473_REG_REMOTE_TEMP, &temp); @@ -116,7 +128,11 @@ xf86I2CReadByte(dev, ADT7473_REG_TACH1_LB, &count_lb); xf86I2CReadByte(dev, ADT7473_REG_TACH1_HB, &count_hb); count = (count_hb << 8) | count_lb; - + + /* GT200 boards seem to use two phases instead of a single, the fan speed is twice as high */ + if(dev->arch & GT200) + count *= 2; + /* RPM = 60*90k pulses / (number of counts that fit in a pulse) */ return 90000*60/count; } diff -Nru nvclock-0.8b3/src/backend/back_bsd.c nvclock-0.8b4/src/backend/back_bsd.c --- nvclock-0.8b3/src/backend/back_bsd.c 2008-01-03 20:08:43.000000000 +0000 +++ nvclock-0.8b4/src/backend/back_bsd.c 2008-12-27 20:40:06.000000000 +0000 @@ -48,6 +48,7 @@ NVClock nvclock; NVCard *nv_card = NULL; +static int probe_devices(); static void *map_dev_mem (int fd, unsigned long Base, unsigned long Size); static void unmap_dev_mem (unsigned long Base, unsigned long Size); @@ -198,11 +199,13 @@ nv_card->PEXTDEV = map_dev_mem(fd, nv_card->reg_address + 0x101000, 0x1000); nv_card->PFB = map_dev_mem(fd, nv_card->reg_address + 0x100000, 0x1000); /* normally pmc is till 0x2000 but extended it for nv40 */ - nv_card->PMC = map_dev_mem(fd, nv_card->reg_address + 0x000000, 0xffff); + nv_card->PMC = map_dev_mem(fd, nv_card->reg_address + 0x000000, 0x2ffff); nv_card->PCIO = map_dev_mem(fd, nv_card->reg_address + 0x601000, 0x2000); + nv_card->PDISPLAY = map_dev_mem(fd, nv_card->reg_address + NV_PDISPLAY_OFFSET, NV_PDISPLAY_SIZE); nv_card->PRAMDAC = map_dev_mem(fd, nv_card->reg_address + 0x680000, 0x2000); + nv_card->PRAMIN = map_dev_mem(fd, nv_card->reg_address + NV_PRAMIN_OFFSET, NV_PRAMIN_SIZE); nv_card->PROM = map_dev_mem(fd, nv_card->reg_address + 0x300000, 0xffff); - + /* On Geforce 8xxx cards it appears that the pci config header has been moved */ if(nv_card->arch & NV5X) nv_card->PBUS = map_dev_mem(fd, nv_card->reg_address + 0x88000, 0x100); @@ -218,9 +221,11 @@ { unmap_dev_mem((unsigned long)nv_card->PEXTDEV, 0x1000); unmap_dev_mem((unsigned long)nv_card->PFB, 0x1000); - unmap_dev_mem((unsigned long)nv_card->PMC, 0x2ffff); + unmap_dev_mem((unsigned long)nv_card->PMC, 0xffff); unmap_dev_mem((unsigned long)nv_card->PCIO, 0x2000); + unmap_dev_mem((unsigned long)nv_card->PDISPLAY, NV_PDISPLAY_SIZE); unmap_dev_mem((unsigned long)nv_card->PRAMDAC, 0x2000); + unmap_dev_mem((unsigned long)nv_card->PRAMIN, NV_PRAMIN_SIZE); unmap_dev_mem((unsigned long)nv_card->PROM, 0xffff); } diff -Nru nvclock-0.8b3/src/backend/back_linux.c nvclock-0.8b4/src/backend/back_linux.c --- nvclock-0.8b3/src/backend/back_linux.c 2008-01-03 20:08:43.000000000 +0000 +++ nvclock-0.8b4/src/backend/back_linux.c 2008-12-23 20:08:47.000000000 +0000 @@ -246,7 +246,9 @@ /* normally pmc is till 0x2000 but extended it for nv40 */ nv_card->PMC = map_dev_mem(fd, nv_card->reg_address + 0x000000, 0x2ffff); nv_card->PCIO = map_dev_mem(fd, nv_card->reg_address + 0x601000, 0x2000); + nv_card->PDISPLAY = map_dev_mem(fd, nv_card->reg_address + NV_PDISPLAY_OFFSET, NV_PDISPLAY_SIZE); nv_card->PRAMDAC = map_dev_mem(fd, nv_card->reg_address + 0x680000, 0x2000); + nv_card->PRAMIN = map_dev_mem(fd, nv_card->reg_address + NV_PRAMIN_OFFSET, NV_PRAMIN_SIZE); nv_card->PROM = map_dev_mem(fd, nv_card->reg_address + 0x300000, 0xffff); /* On Geforce 8xxx cards it appears that the pci config header has been moved */ @@ -266,7 +268,9 @@ unmap_dev_mem((unsigned long)nv_card->PFB, 0x1000); unmap_dev_mem((unsigned long)nv_card->PMC, 0xffff); unmap_dev_mem((unsigned long)nv_card->PCIO, 0x2000); + unmap_dev_mem((unsigned long)nv_card->PDISPLAY, NV_PDISPLAY_SIZE); unmap_dev_mem((unsigned long)nv_card->PRAMDAC, 0x2000); + unmap_dev_mem((unsigned long)nv_card->PRAMIN, NV_PRAMIN_SIZE); unmap_dev_mem((unsigned long)nv_card->PROM, 0xffff); } diff -Nru nvclock-0.8b3/src/backend/back_win32.c nvclock-0.8b4/src/backend/back_win32.c --- nvclock-0.8b3/src/backend/back_win32.c 2008-01-03 20:08:43.000000000 +0000 +++ nvclock-0.8b4/src/backend/back_win32.c 2008-10-25 15:34:41.000000000 +0000 @@ -135,6 +135,7 @@ /* normally pmc is till 0x2000 but extended it for nv40 */ nv_card->PMC = pMapPhysToLinear(nv_card->reg_address + 0x000000, 0x2ffff, &hmem); nv_card->PCIO = pMapPhysToLinear(nv_card->reg_address + 0x601000, 0x2000, &hmem); + nv_card->PDISPLAY = pMapPhysToLinear(nv_card->reg_address + NV_PDISPLAY, NV_PDISPLAY_LENGTH, &hmem); nv_card->PRAMDAC = pMapPhysToLinear(nv_card->reg_address + 0x680000, 0x2000, &hmem); nv_card->PROM = pMapPhysToLinear(nv_card->reg_address + 0x300000, 0xffff, &hmem); diff -Nru nvclock-0.8b3/src/backend/backend.c nvclock-0.8b4/src/backend/backend.c --- nvclock-0.8b3/src/backend/backend.c 2008-01-03 20:08:43.000000000 +0000 +++ nvclock-0.8b4/src/backend/backend.c 2008-03-24 17:17:00.000000000 +0000 @@ -95,7 +95,7 @@ /* Also retrieve the irq which is used to sync nvclock and NV-CONTROL */ NVGetAttribute(nvclock.dpy, 0, 0, NV_IRQ, &irq); - if(have_coolbits && (nv_card->gpu == DESKTOP) && (nv_card->irq == irq)) + if(have_coolbits && (nv_card->irq == irq)) { nv_card->caps |= COOLBITS_OVERCLOCKING; diff -Nru nvclock-0.8b3/src/backend/backend.h nvclock-0.8b4/src/backend/backend.h --- nvclock-0.8b3/src/backend/backend.h 2008-01-03 20:08:43.000000000 +0000 +++ nvclock-0.8b4/src/backend/backend.h 2008-12-23 22:35:15.000000000 +0000 @@ -51,8 +51,8 @@ int32_t pciReadLong(unsigned short devbusfn, long offset); /* Bios related stuff */ -void dump_bios(char *filename); -struct nvbios* read_bios(char *filename); +void dump_bios(const char *filename); +struct nvbios* read_bios(const char *filename); /* NV-CONTROL overclocking functions */ float nvcontrol_get_gpu_speed(); diff -Nru nvclock-0.8b3/src/backend/bios.c nvclock-0.8b4/src/backend/bios.c --- nvclock-0.8b3/src/backend/bios.c 2008-01-04 13:05:38.000000000 +0000 +++ nvclock-0.8b4/src/backend/bios.c 2009-01-03 16:37:18.000000000 +0000 @@ -30,6 +30,7 @@ #include "backend.h" #include "nvclock.h" +#include "nvreg.h" #include #include #include @@ -45,7 +46,7 @@ #define READ_LONG(rom, offset) (READ_INT(rom, offset+4)<<32 | READ_INT(rom, offset)) static unsigned int locate(char *rom, char *str, int offset); -struct nvbios *read_bios(char *file); +struct nvbios *read_bios(const char *file); static struct nvbios *parse_bios(char *rom); typedef struct @@ -146,7 +147,7 @@ */ static char *nv40_bios_version_to_str(char *rom, short offset) { - char res[15]; + char res[16]; int version = READ_INT(rom, offset); unsigned char extra = rom[offset+4]; @@ -358,6 +359,12 @@ #endif offset += 18; break; + case 0x97: /* 0x97 */ +#if DEBUG + printf("'%c'\t%08x %08x\n", id, READ_INT(rom, offset+1), READ_INT(rom, offset+5)); +#endif + offset += 13; + break; default: printf("Unhandled init script entry with id '%c' at %04x\n", id, offset); return 0; @@ -884,22 +891,131 @@ #else -void dump_bios(char *filename) +void dump_bios(const char *filename) { int i; FILE *fp = NULL; + char *rom = calloc(NV_PROM_SIZE, sizeof(char)); - /* enable bios parsing; on some boards the display might turn off */ - nv_card->PMC[0x1850/4] = 0x0; + if(!rom) + { + fprintf(stderr, "Unable to allocate memory for shadowing the bios image\n"); + return; + } - /* try to dump the bios */ + /* Try to obtain a copy of the bios first from PRAMIN later from the (slow) ROM. + / Dumping from ROM might fail on laptops as for some reason there is no ROM on some laptops. + */ + if(!load_bios_pramin(rom)) + { + if(!load_bios_prom(rom)) + { + fprintf(stderr, "Unable to shadow the video bios\n"); + free(rom); + return; + } + } + + /* Try to dump the bios to a file */ fp = fopen(filename, "w+"); - if(!fp) return; + if(!fp) return; - for(i=0; i < 0xffff; i++) + for(i=0; iarch) + return 0; + + /* On NV5x cards we need to let pramin point to the bios */ + if (nv_card->arch & NV5X) + { + uint32_t vbios_vram = (nv_card->PDISPLAY[0x9f04/4] & ~0xff) << 8; + + if (!vbios_vram) + vbios_vram = (nv_card->PMC[0x1700/4] << 16) + 0xf0000; + + old_bar0_pramin = nv_card->PMC[0x1700/4]; + nv_card->PMC[0x1700/4] = (vbios_vram >> 16); + } + + /* Copy bios data */ + bios = (char*)nv_card->PRAMIN; + memcpy(data, bios, NV_PROM_SIZE); + + if (nv_card->arch & NV5X) + nv_card->PMC[0x1700/4] = old_bar0_pramin; + + /* Make sure the bios is correct */ + if(verify_bios(data)) + return 1; + else + return 0; +} + +/* Load the video bios from the ROM. Note laptops might not have a ROM which can be accessed from the GPU */ +int load_bios_prom(char *data) +{ + int i; + + /* enable bios parsing; on some boards the display might turn off */ + nv_card->PMC[0x1850/4] = 0x0; + + for(i=0; iPROM[i]; - data = nv_card->PROM[i]; - data = nv_card->PROM[i]; - data = nv_card->PROM[i]; - data = nv_card->PROM[i]; - fprintf(fp, "%c", data); + data[i] = nv_card->PROM[i]; + data[i] = nv_card->PROM[i]; + data[i] = nv_card->PROM[i]; + data[i] = nv_card->PROM[i]; + data[i] = nv_card->PROM[i]; } - fclose(fp); /* disable the rom; if we don't do it the screens stays black on some cards */ nv_card->PMC[0x1850/4] = 0x1; + + /* Make sure the bios is correct */ + if(verify_bios(data)) + return 1; + else + return 0; } -#endif /* This function tries to read a copy of the bios from harddrive. If that doesn't exist it will dump the bios and then read it. You might wonder why we don't read the bios from card. The reason behind that is that some bioses are slow to read (can take seconds) and second on some cards (atleast on my gf2mx) the screen becomes black if I enable reading of the rom. */ -struct nvbios *read_bios(char *file) +struct nvbios *read_bios(const char *file) { - int fd = 0; - char *rom = NULL; struct nvbios *res; + char *rom = calloc(NV_PROM_SIZE, sizeof(char)); - if((fd = open(file, O_RDONLY)) == -1) - return NULL; /* We might need to redump the bios */ - - rom = mmap(0, 0xffff, PROT_READ, MAP_SHARED, fd, 0); if(!rom) - return NULL; /* We might need to redump the bios */ + return NULL; + + if(!load_bios_pramin(rom)) + { + if(!load_bios_file(file, rom)) + { + free(rom); + return NULL; + } + } /* Do the actual bios parsing */ res = parse_bios(rom); - /* Close the bios */ - close(fd); + /* Cleanup the mess */ + free(rom); return res; } diff -Nru nvclock-0.8b3/src/backend/config.c nvclock-0.8b4/src/backend/config.c --- nvclock-0.8b3/src/backend/config.c 2008-01-03 20:08:43.000000000 +0000 +++ nvclock-0.8b4/src/backend/config.c 2008-12-12 20:14:21.000000000 +0000 @@ -270,7 +270,10 @@ if(!(home = getenv("HOME"))) { - /* error */ + /* This code should only get entered when nvclock is started at system startup. + / The rest of the code and mainly the GTK version isn't prepared for this yet. + */ + return 1; } nvclock.path = malloc(strlen(home) + strlen("/.nvclock") +1); @@ -288,6 +291,7 @@ set_error_str(buf); return 0; } + stat(nvclock.path, &stat_buf); } /* Check if .nvclock really is a directory. For some users it was a file and this led to a segfault. */ diff -Nru nvclock-0.8b3/src/backend/info.c nvclock-0.8b4/src/backend/info.c --- nvclock-0.8b3/src/backend/info.c 2008-01-03 20:08:43.000000000 +0000 +++ nvclock-0.8b4/src/backend/info.c 2008-12-29 00:00:34.000000000 +0000 @@ -226,7 +226,9 @@ { 0x240, "nVidia Geforce 6150", NFORCE }, { 0x241, "nVidia Geforce 6150LE", NFORCE }, { 0x242, "nVidia Geforce 6100", NFORCE }, + { 0x244, "nVidia Geforce Go 6150", NFORCE }, { 0x245, "nVidia Quadro NVS 210S / Geforce 6150LE", NFORCE }, + { 0x247, "nVidia Geforce Go 6100", NFORCE }, { 0x2dd, "nVidia Unknown NV4x", DESKTOP }, { 0x2de, "nVidia Unknown NV4x", DESKTOP }, { 0x90, "nVidia G70", DESKTOP }, @@ -242,7 +244,10 @@ { 0x290, "nVidia Geforce 7900GTX", DESKTOP }, { 0x291, "nVidia Geforce 7900GT", DESKTOP }, { 0x292, "nVidia Geforce 7900GS", DESKTOP }, + { 0x293, "nVidia Geforce 7950GX2", DESKTOP }, + { 0x294, "nVidia Geforce 7950GX2", DESKTOP }, { 0x295, "nVidia Geforce 7950GT", DESKTOP }, + { 0x297, "nVidia Geforce Go 7950GTX", MOBILE }, { 0x298, "nVidia Geforce Go 7900GS", MOBILE }, { 0x299, "nVidia Geforce Go 7900GTX", MOBILE }, { 0x29a, "nVidia QuadroFX 2500M", MOBILE }, @@ -326,23 +331,49 @@ { 0x53a, "nVidia Geforce 7050PV nForce 630a", NFORCE}, { 0x53b, "nVidia Geforce 7050PV nForce 630a", NFORCE}, { 0x53e, "nVidia Geforce 7025 nForce 630a", NFORCE}, + { 0x5e0, "nvidia GeForce GT200-400", DESKTOP }, + { 0x5e1, "nvidia GeForce GTX 280", DESKTOP }, + { 0x5e2, "nvidia GeForce GTX 260", DESKTOP }, + { 0x5e7, "nvidia Tesla C1060", DESKTOP }, + { 0x5ed, "nvidia Quadroplex 2200 D2", DESKTOP }, + { 0x5f8, "nvidia Quadroplex 2200 S4", DESKTOP }, + { 0x5f9, "nvidia Quadro CX", DESKTOP }, + { 0x5fd, "nvidia QuadroFX 5800", DESKTOP }, + { 0x5fe, "nvidia QuadroFX 5800", DESKTOP }, { 0x600, "nVidia Geforce 8800GTS 512", DESKTOP }, + { 0x602, "nVidia Geforce 8800GT", DESKTOP }, + { 0x604, "nVidia Geforce 9800GX2", DESKTOP }, + { 0x606, "nVidia Geforce 8800GS", DESKTOP }, + { 0x60d, "nVidia Geforce 8800GS", DESKTOP }, { 0x609, "nVidia Geforce 8800M GTS", MOBILE }, + { 0x60c, "nVidia Geforce 8800M GTX", MOBILE }, + { 0x610, "nVidia Geforce 9600GSO", DESKTOP }, { 0x611, "nVidia Geforce 8800GT", DESKTOP }, + { 0x612, "nVidia Geforce 9800GTX", DESKTOP }, + { 0x614, "nVidia Geforce 9800GT", DESKTOP }, { 0x61a, "nVidia QuadroFX 3700", DESKTOP }, - { 0x6e0, "nVidia G98", DESKTOP }, - { 0x6e1, "nVidia G98", DESKTOP }, + { 0x61c, "nVidia QuadroFX 3600M", MOBILE }, + { 0x622, "nVidia Geforce 9600GT", DESKTOP }, + { 0x623, "nVidia Geforce 9600GS", DESKTOP }, + { 0x640, "nVidia Geforce 9500GT", DESKTOP }, + { 0x643, "nVidia Geforce 9500GT", DESKTOP }, + { 0x647, "nVidia Geforce 9600M GT", MOBILE }, + { 0x648, "nVidia Geforce 9600M GS", MOBILE }, + { 0x649, "nVidia Geforce 9600M GT", MOBILE }, + { 0x64b, "nVidia Geforce 9500M G", MOBILE }, + { 0x6e0, "nVidia Geforce 9300GE", DESKTOP }, + { 0x6e1, "nVidia Geforce 9300GS", DESKTOP }, { 0x6e2, "nVidia Geforce 8400", DESKTOP }, - { 0x6e3, "nVidia G98", DESKTOP }, + { 0x6e3, "nVidia Geforce 8400SE", DESKTOP }, { 0x6e4, "nVidia Geforce 8400GS", DESKTOP }, - { 0x6e5, "nVidia G98", DESKTOP }, - { 0x6e6, "nVidia G98", DESKTOP }, + { 0x6e5, "nVidia Geforce 9300M GS", MOBILE }, + { 0x6e6, "nVidia Geforce G100", DESKTOP }, { 0x6e7, "nVidia G98", DESKTOP }, - { 0x6e8, "nVidia G98", DESKTOP }, - { 0x6e9, "nVidia G98", DESKTOP }, - { 0x6ea, "nVidia G98", DESKTOP }, - { 0x6eb, "nVidia G98", DESKTOP }, - { 0x6ec, "nVidia G98", DESKTOP }, + { 0x6e8, "nVidia Geforce 9200M GS", MOBILE }, + { 0x6e9, "nVidia Geforce 9300M GS", MOBILE }, + { 0x6ea, "nVidia Quadro NVS 150M", MOBILE }, + { 0x6eb, "nVidia Quadro NVS 160M", MOBILE }, + { 0x6ec, "nVidia Geforce G105M", MOBILE }, { 0x6ed, "nVidia G98", DESKTOP }, { 0x6ee, "nVidia G98", DESKTOP }, { 0x6ef, "nVidia G98", DESKTOP }, @@ -354,14 +385,19 @@ { 0x6f5, "nVidia G98", DESKTOP }, { 0x6f6, "nVidia G98", DESKTOP }, { 0x6f7, "nVidia G98", DESKTOP }, - { 0x6f8, "nVidia G98", DESKTOP }, - { 0x6f9, "nVidia G98", DESKTOP }, - { 0x6fa, "nVidia G98", DESKTOP }, - { 0x6fb, "nVidia G98", DESKTOP }, + { 0x6f8, "nVidia Quadro NVS 420", DESKTOP }, + { 0x6f9, "nVidia QuadroFX 370 LP", DESKTOP }, + { 0x6fa, "nVidia Quadro NVS 450", DESKTOP }, + { 0x6fb, "nVidia QuadroFX 370M", MOBILE }, { 0x6fc, "nVidia G98", DESKTOP }, - { 0x6fd, "nVidia G98", DESKTOP }, + { 0x6fd, "nVidia Quadro NVS 295", DESKTOP }, { 0x6fe, "nVidia G98", DESKTOP }, - { 0x6ff, "nVidia G98", DESKTOP }, + { 0x6ff, "nVidia G98-GL", DESKTOP }, + { 0x860, "nVidia Geforce 9300", DESKTOP }, + { 0x861, "nVidia Geforce 9400", DESKTOP }, + { 0x863, "nVidia Geforce 9400M", MOBILE }, + { 0x864, "nVidia Geforce 9300", DESKTOP }, + { 0x865, "nVidia Geforce 9300", DESKTOP }, { 0, NULL, UNKNOWN } }; @@ -466,12 +502,25 @@ case 0x420: /* 8500 'G86' */ arch = G86; break; - case 0x600: /* G92 */ - case 0x610: /* G92 */ + case 0x5e0: /* GT2x0 */ + case 0x5f0: /* GT2x0 */ + arch = GT200; + break; case 0x6e0: /* G98 */ case 0x6f0: /* G98 */ + case 0x860: /* C79 */ arch = G86; break; + case 0x600: /* G92 */ + case 0x610: /* G92 */ + arch = G92; + break; + case 0x620: /* 9600GT 'G94' */ + arch = G94; + break; + case 0x640: /* 9500GT */ + arch = G96; + break; case 0x240: case 0x3d0: /* not sure if this is a C51 too */ case 0x530: /* not sure if the 70xx is C51 too */ @@ -547,6 +596,12 @@ return nv_read_pbus16(PCI_DEVICE_ID); } +/* Retrieve the pci subvendor id */ +static short get_pci_subvendor_id() +{ + return nv_read_pbus16(PCI_SUBSYSTEM_VENDOR_ID); +} + static int set_gpu_pci_id(short id) { if(nv_card->arch & (NV10 | NV20)) @@ -864,13 +919,23 @@ char rmask, rmask_default; switch(nv_card->get_rop_units(&rmask, &rmask_default)) { + case 32: /* Geforce GTX280 */ + return 512; + case 28: /* Geforce GTX260 */ + return 448; case 24: /* 8800GTX */ return 384; case 20: /* 8800GTS */ return 320; + case 16: /* 8800GT */ + return 256; + case 12: /* 8800GS */ + return 192; case 8: /* 8600GT/GTS */ - case 4: /* 8500GT */ + case 4: /* 8500GT; 8400GS boards use the same core and offer 64-bit, how to handle this? */ return 128; + case 2: /* 8300GS */ + return 64; } } /* Generic algorithm for cards up to the Geforce4 */ @@ -986,6 +1051,7 @@ printf("NV_15F4 (0x15f4): %08x\n", nv_card->PMC[0x15f4/4]); printf("NV_15F8 (0x15f8): %08x\n", nv_card->PMC[0x15f8/4]); printf("NV_PBUS_PCI_0 (0x1800): %08x\n", nv_read_pbus(PCI_VENDOR_ID)); + printf("NV_PBUS_PCI_0 (0x182c): %08x\n", nv_read_pbus(PCI_SUBSYSTEM_VENDOR_ID)); if(nv_card->arch & (NV4X | NV5X)) { @@ -1027,9 +1093,14 @@ if(nv_card->arch & NV5X) { printf("NV_E100 (0xe100): %08x\n", nv_card->PMC[0xe100/4]); + printf("NV_E114 (0xe114): %08x\n", nv_card->PMC[0xe114/4]); + printf("NV_E118 (0xe118): %08x\n", nv_card->PMC[0xe118/4]); printf("NV_E11C (0xe11c): %08x\n", nv_card->PMC[0xe11c/4]); printf("NV_E120 (0xe120): %08x\n", nv_card->PMC[0xe120/4]); + printf("NV_E300 (0xe300): %08x\n", nv_card->PMC[0xe300/4]); printf("NV_20008 (0x20008): %08x\n", nv_card->PMC[0x20008/4]); + printf("NV_20400 (0x20400): %08x\n", nv_card->PMC[0x20400/4]); + printf("NV_PDISPLAY_SOR0_REGS_BRIGHTNESS(%x): %08x\n", NV_PDISPLAY_SOR0_REGS_BRIGHTNESS, nv_card->PDISPLAY[NV_PDISPLAY_SOR0_REGS_BRIGHTNESS/4]); } printf("NV_PFB_CFG0 (0x100200): %08x\n", nv_card->PFB[0x200/4]); @@ -1106,6 +1177,9 @@ nv_card->card_name = (char*)get_card_name(nv_card->device_id, &nv_card->gpu); } + /* Set the pci subvendor id */ + nv_card->subvendor_id = get_pci_subvendor_id(); + /* gpu arch/revision */ nv_card->get_gpu_architecture = get_gpu_architecture; nv_card->get_gpu_revision = get_gpu_revision; diff -Nru nvclock-0.8b3/src/backend/lm99.c nvclock-0.8b4/src/backend/lm99.c --- nvclock-0.8b3/src/backend/lm99.c 2007-04-22 18:24:32.000000000 +0000 +++ nvclock-0.8b4/src/backend/lm99.c 2008-12-13 21:56:04.000000000 +0000 @@ -76,24 +76,29 @@ xf86I2CReadByte(dev, LM99_REG_REMOTE_TEMP, &temp); - /* Cards with lm99 chips need an offset of 16C according to the datasheets. - / Further an extra offset of 10C seems to be needed on Geforce6800 cards to match nvidia-settings. - / Last but not least Geforce6600GT boards containing an LM99 sensor seem to need a total offset of 21C. - */ + /* Cards with lm99 chips need an offset of 16C according to the datasheets. */ if(dev->chip_id == LM99) { + temp += 16; + } + + /* The temperature needs to be corrected using an offset which is stored in the bios. + / If no bios has been parsed we fall back to a default value. + */ + if(nv_card->bios) + { + temp += nv_card->bios->sensor_cfg.temp_correction; + } + else + { + /* An extra offset of 10C seems to be needed on Geforce6800 cards to match nvidia-settings. + / Last but not least Geforce6600GT boards containing an LM99 sensor seem to need a +5C offset. + */ if(dev->arch == NV43) - temp += 21; + temp += 5; else if(dev->arch & NV4X) - temp += 26; - else - temp += 16; + temp += 10; } - /* Geforce6 boards need an extra offset of +10C on both LM99 and MAX6659 chipsets. - / The code below is only executed for MAX6659 as we already handle the extra 10C above. - */ - else if(dev->arch & NV4X) - temp += 10; return temp; } diff -Nru nvclock-0.8b3/src/backend/nv40.c nvclock-0.8b4/src/backend/nv40.c --- nvclock-0.8b3/src/backend/nv40.c 2008-01-04 17:35:39.000000000 +0000 +++ nvclock-0.8b4/src/backend/nv40.c 2008-12-12 20:47:13.000000000 +0000 @@ -399,6 +399,12 @@ else temp = nv_card->PMC[0x15b4/4] & 0xff; + if(nv_card->debug) + { + printf("NV_15B4 (0x15B4): %08x\n", nv_card->PMC[0x15b4/4]); + printf("slope=%f, offset=%f, correction=%d\n", slope, offset, correction); + } + return (int)(temp * slope + offset) + correction; } diff -Nru nvclock-0.8b3/src/backend/nv50.c nvclock-0.8b4/src/backend/nv50.c --- nvclock-0.8b3/src/backend/nv50.c 2008-01-03 20:08:43.000000000 +0000 +++ nvclock-0.8b4/src/backend/nv50.c 2009-01-04 10:46:39.000000000 +0000 @@ -75,10 +75,19 @@ case G86: mask = 0x010001; break; + case G92: + mask = 0x0f00ff; + break; + case G94: + mask = 0x0f000f; + break; + case GT200: + mask = 0xff03ff; + break; } if(smask) - *smask = mask & 0xff; + *smask = mask & 0x3ff; if(rmask) *rmask = (mask >> 16) & 0xff; @@ -91,20 +100,24 @@ static int nv50_get_stream_units(char *mask, char *default_mask) { int i, stream_units=0; - unsigned char stream_units_cfg = nv_card->PMC[0x1540/4] & 0xff; + int32_t stream_units_cfg = nv_card->PMC[0x1540/4] & 0x3ff; /* The number of shaders is again stored in 0x1540 - bit7-0: number of unified pixel shaders in blocks of 16 + bit9-0: number of unified pixel shaders in blocks of 16 bit23-16: number of ROP units in blocks of 4 bit31-24: what's in here? */ - for(i=0; i<8; i++) + for(i=0; i<10; i++) if((stream_units_cfg >> i) & 0x1) stream_units++; nv50_get_default_mask(default_mask, 0); *mask = stream_units_cfg; + + if(nv_card->arch == GT200) + return (stream_units * 24); /* GT200 stores stream units in blocks of 24 */ + return (stream_units << 4); /* stream units are stored in blocks of 16 */ } @@ -126,6 +139,45 @@ return (rop_units << 2); /* rop units are stored in blocks of 4 */ } +static float g84_get_fanspeed() +{ + int pwm_divider = nv_card->PMC[0xe11c/4] & 0x7fff; + + /* On most Geforce8/9 cards I have seen the fanspeed register is 'inverted', so + / a low value corresponds with fullspeed (to be exact the register defines the low + / period of a pwm pulse. Though some boards aren't inverted like a 8500GT (G86). I'm + / not sure what we should do about this. If it is possible to whitelist some generations + / or so we should perhaps do that or perhaps there is some setting in the bios? So right + / now 100% would show 0% on a 8500GT. + / + / Further some boards use 0xe114 / 0xe118 instead of 0xe11c / 0xe1220. At least the 9800GTX + / seems to do that. When I have a more clear picture of the situation those should receive support too. + */ + float fanspeed = (float)(pwm_divider - (nv_card->PMC[0xe120/4] & 0x7fff)) * 100.0/(float)pwm_divider; + return fanspeed; +} + +static void g84_set_fanspeed(float speed) +{ + int value; + int pwm_divider = nv_card->PMC[0xe11c/4] & 0x7fff; + + /* For safety reasons we should never disable the fan by not putting it below 10%; further negative values don't exist ;) */ + if(speed < 10 || speed > 100) + return; + + /* Bit31 must be set else the hardware doesn't seem to do anything with the changes + / Bit30-16 contain some magical bits on 9500GT and other cards which we should preserve. + / On a 9500gt the contents of 0xe120 could be e.g. 0x0300010e with a pwm_divider of 0x21d. + / + / Note Oxe300 is also related to the fanspeed. By default it seems to contain 0x100 on + / 9600GT and other cards. Setting this value to 0x300 seems to set the fanspeed to a fixed + / value. Apparently 0xe300 acts like a multiplexer? + */ + value = 0x80000000 | (nv_card->PMC[0xe120/4] & 0x7fff0000) | (((int)(100 - speed) * pwm_divider/100) & 0x7fff); + nv_card->PMC[0xe120/4] = value; +} + /* Reading of the internal gpu sensor, it not entirely correct yet */ static int nv50_get_gpu_temp(void *sensor) { @@ -138,10 +190,69 @@ offset = -227.0; slope = 430.0/10000.0; + if(nv_card->debug) + { + printf("NV_20008 (0x20008): %08x\n", nv_card->PMC[0x20008/4]); + printf("slope=%f, offset=%f, correction=%d\n", slope, offset, correction); + } + temp = nv_card->PMC[0x20008/4] & 0x1fff; return (int)(temp * slope + offset) + correction; } +static int g84_get_gpu_temp(void *sensor) +{ + if(nv_card->debug) + { + /* A calibrated value of the temperature is stored in 0x20400, raw in 0x20008 it would require bios info to calibrate it */ + printf("NV_20008 (0x20008): %08x\n", nv_card->PMC[0x20008/4]); + printf("NV_20400 (0x20400): %08x\n", nv_card->PMC[0x20400/4]); + } + + /* A calibrated value of the temperature is stored in 0x20400 */ + return nv_card->PMC[0x20400/4]; +} + +static int g92_get_gpu_temp(void *sensor) +{ + int temp; + float offset; + float divider; + + /* According to a formula on the rivatuner forum Asus uses the following formula: (-13115 + raw_temp)/18.7 + 1. */ + offset = -13115 + 18.7; + divider = 18.7; + + if(nv_card->debug) + { + printf("NV_20008 (0x20008): %08x\n", nv_card->PMC[0x20008/4]); + printf("divider=%f, offset=%f\n", divider, offset); + } + + temp = nv_card->PMC[0x20008/4] & 0x1fff; + return (int)(temp + offset)/divider; +} + + +/* Get current backpanel brightness level on laptops */ +static int nv50_mobile_get_smartdimmer() +{ + int val = nv_card->PDISPLAY[NV_PDISPLAY_SOR0_REGS_BRIGHTNESS/4]; + /* Convert level to a value between 1 and 100 */ + /* For now assume the maximum value is 1024 */ + return ((val / 1024.0 * 100) + 0.5); +} + +/* Adjust backpanel brightness on laptops */ +static void nv50_mobile_set_smartdimmer(int level) +{ + int val; + if(level < 15 || level > 100) + return; + val = (level * 1024 / 100) | NV_PDIPSLAY_SOR0_REGS_BRIGHTNESS_CONTROL_ENABLED; + nv_card->PDISPLAY[NV_PDISPLAY_SOR0_REGS_BRIGHTNESS/4] = val; +} + static int CalcSpeed_nv50(int base_freq, int m1, int m2, int n1, int n2, int p) { return (int)((float)(n1*n2)/(m1*m2) * base_freq) >> p; @@ -199,7 +310,6 @@ static void nv50_set_memory_speed(unsigned int memclk) { - printf("blaat: %d %p %x\n", memclk, nvclock.dpy, nv_card->state); } static float nv50_get_shader_speed() @@ -282,15 +392,66 @@ i2c_sensor_init(); } + /* For now unlock laptops of HP, Samsung (Sanyo), Sony and Zepto. Later on we whould find a better way if there is any. + / Most likely there is some info in the bios which can help us figuring out what smartdimmer method is used. + / The code has been reported to work on the following models: + / - Apple Macbook5,1 (Aluminium), Geforce 9400M, dev=0x863, subvendor=0x106b + / - HP Compaq 8510W, QuadroFX 570M, dev=0x40c, subvendor=0x103c + / - HP Compaq 8710P, QuadroFX 320M, dev=0x40b, subvendor=0x103c + / - Samsung Q210 / Q310 / R510, Geforce 9200M, dev=0x6e8, subvendor=0x144d + / - Sony Vaio models using 8400/8600 GPUs: + / VGN SZ650N, SZ61MN/B, SZ730E, SZ750N, SZ71MN/B, SZ71E, VGN FZ38M, FZ31M, FZ11Z, NR31, AR41E, FZ11S, FZ290, FZ250AE, + / FZ21E, FZ21M, FZ470E, FZ340E, FZ190N, FZ18M, FZ31E, FZ18E, FZ31Z, FZ21Z, FZ31S, AR51SU, AR71S + / - Zepto (unknown model), Geforce 9600M, dev=0x649, subvendor=0x1a46, + */ + if((nv_card->gpu == MOBILE) && + ((nv_card->subvendor_id == PCI_VENDOR_ID_APPLE) || + (nv_card->subvendor_id == PCI_VENDOR_ID_HP) || + (nv_card->subvendor_id == PCI_VENDOR_ID_SANYO) || + (nv_card->subvendor_id == PCI_VENDOR_ID_SONY) || + (nv_card->subvendor_id == PCI_VENDOR_ID_ZEPTO))) + { + nv_card->caps |= SMARTDIMMER; + nv_card->get_smartdimmer = nv50_mobile_get_smartdimmer; + nv_card->set_smartdimmer = nv50_mobile_set_smartdimmer; + } + /* Temperature monitoring; all NV50 cards feature an internal temperature sensor / but only use it when there is no I2C sensor around. */ - if(!(nv_card->caps & GPU_TEMP_MONITORING)) + if((nv_card->arch & NV50) && !(nv_card->caps & GPU_TEMP_MONITORING)) { nv_card->caps |= GPU_TEMP_MONITORING; nv_card->sensor_name = (char*)strdup("GPU Internal Sensor"); nv_card->get_gpu_temp = (int(*)(I2CDevPtr))nv50_get_gpu_temp; } + else if((nv_card->arch & (G84 | G86 | G94 | G96)) && !(nv_card->caps & GPU_TEMP_MONITORING)) + { + nv_card->caps |= GPU_TEMP_MONITORING; + nv_card->sensor_name = (char*)strdup("GPU Internal Sensor"); + nv_card->get_gpu_temp = (int(*)(I2CDevPtr))g84_get_gpu_temp; + } + else if((nv_card->arch & G92) && !(nv_card->caps & GPU_TEMP_MONITORING)) + { + /* Nearly all G92 boards use a ADT7473 except some Asus models. They don't use the bios data properly, so give it its own function */ + nv_card->caps |= GPU_TEMP_MONITORING; + nv_card->sensor_name = (char*)strdup("GPU Internal Sensor"); + nv_card->get_gpu_temp = (int(*)(I2CDevPtr))g92_get_gpu_temp; + } + + + /* Fanspeed adjustment support for several 8600GT 'G84', 9600GT 'G94' and 9600GSO 'G92' boards + / For now only support fanspeed adjustment using pwm registers 0xe11c/0xe120. Assume they are + / active when 0xe11c (pwm divider) is higher than 1. We need a proper method to distinguish between + / the use of 0xe114/0xe118 and 0xe11c/0xe120 and to detect whether the pwm signal needs to be inverted + / or not. Likely there is info in the bios for this. + */ + if((nv_card->arch & (G84 | G86 | G92 | G94 | G96)) && !(nv_card->caps & I2C_FANSPEED_MONITORING) && (nv_card->PMC[0xe11c/4] > 1)) + { + nv_card->caps |= GPU_FANSPEED_MONITORING; + nv_card->get_fanspeed = g84_get_fanspeed; + nv_card->set_fanspeed = g84_set_fanspeed; + } /* Mobile GPU check; we don't want to overclock those unless the user wants it */ if(nv_card->gpu == MOBILE) diff -Nru nvclock-0.8b3/src/backend/nvclock.h nvclock-0.8b4/src/backend/nvclock.h --- nvclock-0.8b3/src/backend/nvclock.h 2008-01-03 20:08:43.000000000 +0000 +++ nvclock-0.8b4/src/backend/nvclock.h 2008-12-28 17:53:23.000000000 +0000 @@ -48,7 +48,11 @@ #define NV50 (1<<17) #define G84 (1<<18) #define G86 (1<<19) -#define NV5X (NV50 | G84 | G86) +#define G92 (1<<20) +#define G94 (1<<21) +#define G96 (1<<22) +#define GT200 (1<<23) +#define NV5X (NV50 | G84 | G86 | G92 | G94 | G96 | GT200) #define NV_ERR_NO_DEVICES_FOUND 1 #define NV_ERR_NO_DRIVERS_FOUND 2 @@ -162,10 +166,10 @@ struct voltage volt_lst[4]; short perf_entries; - struct performance perf_lst[3]; + struct performance perf_lst[4]; short pll_entries; - struct pll pll_lst[8]; + struct pll pll_lst[16]; struct sensor sensor_cfg; @@ -182,6 +186,7 @@ short number; /* internal card number; used by the gtk client and set_card to see if we really need to switch cards */ short caps; /* A bitmask that contains what card features are supported; A normal gpu can do gpu/memory overclocking but a nforce can do only gpu. */ short device_id; + short subvendor_id; int arch; /* Architecture NV10, NV15, NV20 ..; for internal use only as we don't list all architectures */ unsigned int reg_address; char *dev_name; /* /dev/mem or /dev/nvidiaX */ @@ -199,8 +204,10 @@ int mem_mapped; /* Check for set_card to see if the memory has been mapped or not. */ volatile unsigned int *PFB; volatile unsigned int *PBUS; + volatile unsigned int *PDISPLAY; /* NV50 display registers */ volatile unsigned int *PMC; volatile unsigned int *PRAMDAC; + volatile unsigned int *PRAMIN; volatile unsigned int *PEXTDEV; volatile unsigned char *PROM; /* Nvidia bios */ volatile unsigned char *PCIO; diff -Nru nvclock-0.8b3/src/backend/nvreg.h nvclock-0.8b4/src/backend/nvreg.h --- nvclock-0.8b3/src/backend/nvreg.h 2007-08-30 16:47:04.000000000 +0000 +++ nvclock-0.8b4/src/backend/nvreg.h 2008-12-29 10:22:29.000000000 +0000 @@ -21,7 +21,14 @@ /* PCI stuff */ #define PCI_VENDOR_ID 0x0 /* 16-bit */ +# define PCI_VENDOR_ID_APPLE 0x106b +# define PCI_VENDOR_ID_HP 0x103c +# define PCI_VENDOR_ID_SANYO 0x144d /* Samsung laptops use the Sanyo vendor id */ +# define PCI_VENDOR_ID_SONY 0x104d +# define PCI_VENDOR_ID_ZEPTO 0x1a46 #define PCI_DEVICE_ID 0x2 /* 16-bit */ +#define PCI_SUBSYSTEM_VENDOR_ID 0x2c /* 16-bit */ +#define PCI_SUBSYSTEM_ID 0x2e /* 16-bit */ #define PCI_CAPABILITY_LIST 0x34 #define PCI_CAP_LIST_ID 0x0 #define PCI_CAP_LIST_NEXT 0x1 @@ -58,6 +65,20 @@ # define NV_PMC_BOOT_0_REVISION_MAJOR 0xf0 /* in general A or B, on pre-NV10 it was different */ # define NV_PMC_BOOT_0_REVISION_MASK 0xff +/* PDISPLAY */ +#define NV_PDISPLAY_OFFSET 0x610000 +#define NV_PDISPLAY_SIZE 0x10000 +#define NV_PDISPLAY_SOR0_REGS_BRIGHTNESS 0xc084 +# define NV_PDIPSLAY_SOR0_REGS_BRIGHTNESS_CONTROL_ENABLED 0x80000000 + +/* PRAMIN */ +#define NV_PRAMIN_OFFSET 0x00700000 +#define NV_PRAMIN_SIZE 0x00100000 + +/* PROM */ +#define NV_PROM_OFFSET 0x300000 +#define NV_PROM_SIZE 0xffff /* size in bytes */ + /* NV4X registers * * 0xc040: used to enble/disable parts of the GPU? diff -Nru nvclock-0.8b3/src/backend/utils.c nvclock-0.8b4/src/backend/utils.c --- nvclock-0.8b3/src/backend/utils.c 2007-12-02 21:30:17.000000000 +0000 +++ nvclock-0.8b4/src/backend/utils.c 2008-12-12 20:14:21.000000000 +0000 @@ -49,6 +49,9 @@ case 0x50: sprintf(buf, "NV50/G80"); /* 8800 */ break; + case 0xa0: + sprintf(buf, "GT200"); /* Geforce GTX260/280 */ + break; default: if(arch <= 0x44) /* The NV44/6200TC is the last card with only an NV name */ sprintf(buf, "NV%X", arch); diff -Nru nvclock-0.8b3/src/backend/xf86i2c.h nvclock-0.8b4/src/backend/xf86i2c.h --- nvclock-0.8b3/src/backend/xf86i2c.h 2007-04-22 18:24:33.000000000 +0000 +++ nvclock-0.8b4/src/backend/xf86i2c.h 2008-12-13 20:37:32.000000000 +0000 @@ -62,7 +62,7 @@ int StartTimeout; /* usec */ short chip_id; /* type of i2c chip; required atleast by the lm99 to decide whether to add an offset or not */ - short arch; /* architecture to which the gpu belongs; the lm99 code needs this for adding offsets too */ + int arch; /* architecture to which the gpu belongs; the lm99 code needs this for adding offsets too */ char *chip_name; I2CSlaveAddr SlaveAddr; diff -Nru nvclock-0.8b3/src/gtk/Makefile.in nvclock-0.8b4/src/gtk/Makefile.in --- nvclock-0.8b3/src/gtk/Makefile.in 2005-09-02 08:36:32.000000000 +0000 +++ nvclock-0.8b4/src/gtk/Makefile.in 2008-05-11 10:25:46.000000000 +0000 @@ -7,9 +7,9 @@ libbackend=../backend/libbackend.a libnvcontrol=../nvcontrol/libnvcontrol.a -prefix=@prefix@ -exec_prefix=@exec_prefix@ -bindir=@bindir@ +prefix=$(DESTDIR)@prefix@ +exec_prefix=$(DESTDIR)@exec_prefix@ +bindir=$(DESTDIR)@bindir@ ifeq ($(HAVE_GTK2), yes) PROGRAM=nvclock_gtk @@ -46,4 +46,4 @@ $(INSTALL_APP) uninstall: - $(UNINSTALL_APP) \ No newline at end of file + $(UNINSTALL_APP) diff -Nru nvclock-0.8b3/src/gtk/gl.c nvclock-0.8b4/src/gtk/gl.c --- nvclock-0.8b3/src/gtk/gl.c 2008-01-03 20:08:44.000000000 +0000 +++ nvclock-0.8b4/src/gtk/gl.c 2008-05-30 23:09:19.000000000 +0000 @@ -136,6 +136,10 @@ /* Wrapper around NVGetAttribute used for configuration file support */ int GLGetAttribute(config *conf, Display *dpy, int screen, unsigned int disp_mask, unsigned int option, int *value) { + /* Verify if the option is available before continuing */ + if(!NVGetAttribute(dpy, screen, disp_mask, option, value)) + return 0; + /* When initialize is set, we will bypass NVGetAttribute and read the values / from the configuration file. */ @@ -437,7 +441,7 @@ { glx_vendor = (char*)pglXQueryServerString(dpy, screen, GLX_VENDOR); glx_version = (char*)pglXQueryServerString(dpy, screen, GLX_VERSION); - glx_direct = (char*)pglXIsDirect(dpy, ctx) ? "Yes" : "No"; + glx_direct = (char*)(pglXIsDirect(dpy, ctx) ? "Yes" : "No"); gl_vendor = (char*)pglGetString(GL_VENDOR); gl_renderer = (char*)pglGetString(GL_RENDERER); gl_version = (char*)pglGetString(GL_VERSION); diff -Nru nvclock-0.8b3/src/gtk/hw.c nvclock-0.8b4/src/gtk/hw.c --- nvclock-0.8b3/src/gtk/hw.c 2008-01-03 20:08:44.000000000 +0000 +++ nvclock-0.8b4/src/gtk/hw.c 2008-05-11 10:25:46.000000000 +0000 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff -Nru nvclock-0.8b3/src/gtk/main.c nvclock-0.8b4/src/gtk/main.c --- nvclock-0.8b3/src/gtk/main.c 2008-01-04 17:32:38.000000000 +0000 +++ nvclock-0.8b4/src/gtk/main.c 2009-01-03 17:11:48.000000000 +0000 @@ -58,7 +58,7 @@ window_nvclock = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size(GTK_WINDOW(window_nvclock), 540, 280); - gtk_window_set_title(GTK_WINDOW(window_nvclock), "NVClock 0.8 (Beta3)"); + gtk_window_set_title(GTK_WINDOW(window_nvclock), "NVClock 0.8 (Beta4)"); main_window = (struct MainWindow*)calloc(1, sizeof(struct MainWindow)); @@ -255,6 +255,9 @@ { GtkWidget *window_nvclock; + gtk_set_locale (); + gtk_init (&argc, &argv); + /* Initialize nvclock. This must be done here instead of in the hardware backend / because of the configuration file which gets initialized by init_nvclock. */ @@ -269,9 +272,6 @@ return 0; } - gtk_set_locale (); - gtk_init (&argc, &argv); - window_nvclock = create_window_main (); gtk_widget_show (window_nvclock); diff -Nru nvclock-0.8b3/src/nvclock.c nvclock-0.8b4/src/nvclock.c --- nvclock-0.8b3/src/nvclock.c 2008-01-04 17:32:57.000000000 +0000 +++ nvclock-0.8b4/src/nvclock.c 2009-01-04 10:54:28.000000000 +0000 @@ -61,7 +61,7 @@ int usage() { - printf("NVClock v0.8 (Beta3)\n\n"); + printf("NVClock v0.8 (Beta4)\n\n"); printf("Using NVClock you can overclock your Nvidia videocard under Linux and FreeBSD.\nUse this program at your own risk, because it can damage your system!\n\n"); printf("Usage: ./nvclock [options]\n\n"); printf("Overclock options:\n"); @@ -78,7 +78,7 @@ printf(" -F --fanspeed speed\t\tAdjust the fanspeed; speed is a value between 10 and 100, a delta +10/-10 or 'auto'\n"); printf(" -P --punit mask\t\tActivate extra pixel pipelines. (NV4X only)\n"); printf(" -Q --deviceid digit\t\tAdjust the last digit of the pci id.\n"); - printf(" -S --smartdimmer level\tAdjust brightness of the backlight; level is a value between 15 and 100 or a delta like +10/-10. (NV4X laptops only for now)\n"); + printf(" -S --smartdimmer level\tAdjust brightness of the backlight; level is a value between 15 and 100 or a delta like +10/-10.\n"); printf(" -T --temperature\t\tShow the GPU temperatures.\n"); printf(" -V --vunit mask\t\tActivate extra vertex pipelines. (NV4X only)\n"); printf(" -i --info\t\t\tShow detailed card info.\n"); @@ -999,7 +999,7 @@ nv_card->set_i2c_fanspeed_pwm(nv_card->sensor, dutycycle); /* It takes a short time for the fanspeed to change */ - usleep(100); + usleep(10000); printf("Fanspeed: %d RPM\n", nv_card->get_i2c_fanspeed_rpm(nv_card->sensor)); printf("New PWM duty cycle: %.1f\n", nv_card->get_i2c_fanspeed_pwm(nv_card->sensor)); } @@ -1034,7 +1034,7 @@ if(!(nv_card->caps & SMARTDIMMER)) { fprintf(stderr, "Error!\n"); - fprintf(stderr, "Smartdimmer is only supported on certain laptops using a Geforce 6200/7x00Go. If you want support on your laptop contact the author.\n"); + fprintf(stderr, "Smartdimmer is only supported on certain (HP/Samsung/Sony/Zepto) laptops using a Geforce 6200/7x00Go/8x00Go. If you want support on your laptop contact the author.\n"); return 0; } @@ -1061,6 +1061,7 @@ nv_card->set_smartdimmer(brightness); printf("New Smartdimmer level: %d%%\n", nv_card->get_smartdimmer()); free(smartdimmer); + return 0; } if(punit_opt && (nv_card->caps & PIPELINE_MODDING) && force_opt) @@ -1179,6 +1180,18 @@ printf("=> GPU temperature: %dC\n", nv_card->get_gpu_temp(nv_card->sensor)); if(nv_card->caps & (BOARD_TEMP_MONITORING)) printf("=> Board temperature: %dC\n", nv_card->get_board_temp(nv_card->sensor)); + +#ifdef HAVE_NVCONTROL + /* Some NV-CONTROL debugging code useful for calibration */ + if(nv_card->debug && nvclock.dpy) + { + int gpu_temp, board_temp; + if(NVGetAttribute(nvclock.dpy, 0, 0, NV_GPU_TEMPERATURE, &gpu_temp)) + printf("=> GPU temperature according to NV-CONTROL: %d\n", gpu_temp); + if(NVGetAttribute(nvclock.dpy, 0, 0, NV_AMBIENT_TEMPERATURE, &board_temp)) + printf("=> Board temperature according to NV-CONTROL: %d\n", board_temp); + } +#endif } else fprintf(stderr, "Error: temperature monitoring isn't supported on your videocard.\n"); @@ -1388,6 +1401,12 @@ if(!backend_opt && nv_card->caps & COOLBITS_OVERCLOCKING) nv_card->set_state(STATE_BOTH); + if((nv_card->state == STATE_LOWLEVEL) && (nv_card->arch & NV5X)) + { + fprintf(stderr, "Error: NVClock doesn't offer lowlevel overclocking on NV50/G8x/G9x/GT200 hardware (yet).\nIf you want to overclock your card using the Nvidia drivers instead add the line:\n Option \"Coolbits\" \"1\" to the screen or device section in your xorg.conf and then try NVClock again.\n"); + return 0; + } + if(reset_opt) { if(nv_card->gpu == MOBILE && !force_opt) diff -Nru nvclock-0.8b3/src/qt/Makefile.in nvclock-0.8b4/src/qt/Makefile.in --- nvclock-0.8b3/src/qt/Makefile.in 2005-09-02 08:36:32.000000000 +0000 +++ nvclock-0.8b4/src/qt/Makefile.in 2008-05-11 10:25:46.000000000 +0000 @@ -8,9 +8,9 @@ HAVE_QT=@HAVE_QT@ libbackend=../backend/libbackend.a -prefix=@prefix@ -exec_prefix=@exec_prefix@ -bindir=@bindir@ +prefix=$(DESTDIR)@prefix@ +exec_prefix=$(DESTDIR)@exec_prefix@ +bindir=$(DESTDIR)@bindir@ ifeq ($(HAVE_QT), yes) PROGRAM=nvclock_qt diff -Nru nvclock-0.8b3/src/smartdimmer.c nvclock-0.8b4/src/smartdimmer.c --- nvclock-0.8b3/src/smartdimmer.c 1970-01-01 00:00:00.000000000 +0000 +++ nvclock-0.8b4/src/smartdimmer.c 2009-01-03 17:11:22.000000000 +0000 @@ -0,0 +1,161 @@ +/* NVClock Smartdimmer 0.8 + * + * Originally SmartDimmer was a friendly fork of NVClock to allow adjustment + * of backlight level on some Sony laptops. Initially there was no code for this + * in NVClock. When NVClock added the code SmartDimmer became obsolete but people + * kept using SmartDimmer while it didn't get updated. For that reason SmartDimmer + * is now part of NVClock. + * + * Copyright(C) 2001-2008 Roderick Colenbrander + * + * site: http://NVClock.sourceforge.net + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +/****************************************************************************** + * smartdimmer.c * + * * + * SmartDimmer adjustment tool. * + * Thanks to Thunderbird and sk1p from #nvclock @ freenode for their help :) * + * * + * July 23, 2005 * + * Erik Waling * + ******************************************************************************/ + +#include +#include +#include +#include "nvclock.h" + +/* for command line arguments */ +#define SET_BIT 1 +#define GET_BIT 2 +#define INC_BIT 4 +#define DEC_BIT 8 + +static struct option long_opts[] = { + { "get" , no_argument , 0, 'g' }, + { "set" , required_argument, 0, 's' }, + { "increase", no_argument , 0, 'i' }, + { "decrease", no_argument , 0, 'd' }, + { "help" , no_argument , 0, 'h' }, + { 0 , 0 , 0, 0 } +}; + +void sd_usage(char *argv0) +{ + printf("NVClock SmartDimmer adjustment tool version 0.8b4.\n\n"); + printf("Usage: %s [OPTION]...\n\n", argv0); + printf("Options:\n"); + printf("\t-g --get\t\tQuery brightness level.\n"); + printf("\t-s --set \tSet brightness level (15-100)\n"); + printf("\t-i --increase\t\tIncrease brightness with one level.\n"); + printf("\t-d --decrease\t\tDecrease brightness with one level.\n"); + printf("\t-h --help\t\tPrints this help text.\n\n"); + +} + +int sd_init() +{ + if (!init_nvclock()) + return -1; + + if (!set_card(0)) + return -2; + + return 0; +} + +int main(int argc, char *argv[]) +{ + int optind = 0, options = 0, setvalue = 0; + int c; + + if (argc < 2) + { + sd_usage(argv[0]); + return 0; + } + + while ((c = getopt_long(argc, argv, "gs:idh", long_opts, &optind)) != -1) + { + switch (c) + { + case '?': + fprintf(stderr, "\nTry `%s --help' for help.\n", argv[0]); + return 1; + case 'h': + sd_usage(argv[0]); + return 0; + case 'g': + options |= GET_BIT; + break; + case 's': + if (isdigit(*optarg)) { + setvalue = atoi(optarg); + options |= SET_BIT; + } else { + fprintf(stderr, "Illegal option value (-s): " + "Value has to be a non-negative number.\n"); + return 1; + } + break; + case 'i': + options |= INC_BIT; + break; + case 'd': + options |= DEC_BIT; + break; + } + } + + if (!options) + { + sd_usage(argv[0]); + return 1; + } + + switch (sd_init()) + { + case -1: + fprintf(stderr, "init_nvclock() failed!\n"); + return 2; + case -2: + fprintf(stderr, "set_card() failed!\n"); + return 3; + } + + if(!(nv_card->caps & SMARTDIMMER)) + { + fprintf(stderr, "Error!\n"); + fprintf(stderr, "Smartdimmer is only supported on certain (HP/SamsungSony/Zepto) laptops using a Geforce 6200/7x00Go/8x00Go. If you want support on your laptop contact the author.\n"); + return 0; + } + + if (options & INC_BIT) + nv_card->set_smartdimmer(nv_card->get_smartdimmer() + 1); + + if (options & DEC_BIT) + nv_card->set_smartdimmer(nv_card->get_smartdimmer() - 1); + + if (options & SET_BIT) + nv_card->set_smartdimmer(setvalue); + + if (options & GET_BIT) + printf("SmartDimmer level: %d\n", nv_card->get_smartdimmer()); + + return 0; +} diff -Nru nvclock-0.8b3/stamp-h nvclock-0.8b4/stamp-h --- nvclock-0.8b3/stamp-h 1970-01-01 00:00:00.000000000 +0000 +++ nvclock-0.8b4/stamp-h 2007-08-29 11:32:47.000000000 +0000 @@ -0,0 +1 @@ +timestamp