summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2013-02-14 20:38:24 -0500
committerBen Skeggs <bskeggs@redhat.com>2013-02-20 15:55:28 +1000
commita821e8ee8021581c5014c4ba82acaa5c97018fe5 (patch)
tree96f50a353aa4d1e2d8ba46d1ba308aaacab5ac31 /bin
parent8305447b882048f0ad3d6231d90162d32719af7c (diff)
downloadnouveau-a821e8ee8021581c5014c4ba82acaa5c97018fe5.tar.gz
nv_aux: tool to access dp aux channels
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'bin')
-rw-r--r--bin/Makefile.am2
-rw-r--r--bin/nv_aux.c118
2 files changed, 119 insertions, 1 deletions
diff --git a/bin/Makefile.am b/bin/Makefile.am
index b445c70b1..39e246b00 100644
--- a/bin/Makefile.am
+++ b/bin/Makefile.am
@@ -4,7 +4,7 @@ bin_PROGRAMS = \
nv_ri08 nv_ri16 nv_ri32 nv_wi08 nv_wi16 nv_wi32 \
nv_rv08 nv_rv16 nv_rv32 nv_wv08 nv_wv16 nv_wv32 \
nv_rs08 nv_rs16 nv_rs32 nv_ws08 nv_ws16 nv_ws32 \
- nv_disp nv_i2c
+ nv_disp nv_i2c nv_aux
AM_CPPFLAGS = -I$(top_srcdir)/nvkm/include \
-I$(top_srcdir)/nvkm \
diff --git a/bin/nv_aux.c b/bin/nv_aux.c
new file mode 100644
index 000000000..9b5204736
--- /dev/null
+++ b/bin/nv_aux.c
@@ -0,0 +1,118 @@
+#include <stdlib.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/class.h>
+
+#include <core/device.h>
+
+#include <subdev/i2c.h>
+
+struct nouveau_object *client;
+struct nouveau_object *device;
+
+static void
+print_chan(struct nouveau_i2c_port *chan)
+{
+ printf("chan 0x%02x: type %04x\n", chan->index, nv_mclass(chan));
+}
+
+int
+main(int argc, char **argv)
+{
+ struct nouveau_i2c_port *chan;
+ struct nouveau_i2c *i2c;
+ int action = -1, index = -1;
+ int addr = -1, val = -1;
+ int ret, c;
+ u8 data;
+
+ while ((c = getopt(argc, argv, "-")) != -1) {
+ switch (c) {
+ case 1:
+ if (action < 0) {
+ if (!strcasecmp(optarg, "rd"))
+ action = 0;
+ else
+ if (!strcasecmp(optarg, "wr"))
+ action = 1;
+ else
+ return -EINVAL;
+ } else
+ if (action >= 0 && index < 0) {
+ index = strtoul(optarg, NULL, 0);
+ } else
+ if (action >= 0 && addr < 0) {
+ addr = strtoul(optarg, NULL, 0);
+ if (addr > 0x000fffff)
+ return -EINVAL;
+ } else
+ if (action >= 1 && data < 0) {
+ val = strtoul(optarg, NULL, 0);
+ if (val > 0xff)
+ return -EINVAL;
+ data = val;
+ } else
+ return -EINVAL;
+ break;
+ }
+ }
+
+ ret = os_client_new(NULL, "error", argc, argv, &client);
+ if (ret)
+ return ret;
+
+ ret = nouveau_object_new(client, ~0, 0, 0x0080,
+ &(struct nv_device_class) {
+ .device = ~0ULL,
+ .disable = ~(NV_DEVICE_DISABLE_MMIO |
+ NV_DEVICE_DISABLE_IDENTIFY|
+ NV_DEVICE_DISABLE_VBIOS |
+ NV_DEVICE_DISABLE_CORE),
+ .debug0 = ~((1 << NVDEV_SUBDEV_VBIOS) |
+ (1 << NVDEV_SUBDEV_I2C)),
+ }, sizeof(struct nv_device_class), &device);
+ if (ret)
+ return ret;
+
+ i2c = nouveau_i2c(device);
+
+ if (action < 0) {
+ list_for_each_entry(chan, &i2c->ports, head) {
+ if ((nv_mclass(chan) & 0x00ff) == 0x06)
+ print_chan(chan);
+ }
+ } else {
+ chan = i2c->find(i2c, index);
+ if (!chan || (nv_mclass(chan) & 0x00ff) != 0x06) {
+ ret = -ENOENT;
+ goto done;
+ }
+
+ print_chan(chan);
+ }
+
+ switch (action) {
+ case 0:
+ ret = nv_rdaux(chan, addr, &data, 1);
+ printf("%05x: ", addr);
+ if (ret < 0)
+ printf("%s\n", strerror(ret));
+ else
+ printf("%02x\n", data);
+ break;
+ case 1:
+ printf("%05x: %02x", addr, data);
+ ret = nv_wraux(chan, addr, &data, 1);
+ if (ret < 0)
+ printf(" - %s", strerror(ret));
+ printf("\n");
+ break;
+ }
+
+done:
+ os_client_del(&client);
+ return ret;
+}