On 12/10/07, Carl-Daniel Hailfinger <[EMAIL PROTECTED]> wrote:
> Thanks for the pointers. I will look into implementing SPI support for
> these cards in a week or so. Ping me if you don't see any code/questions
> until then.

Here is the code for a simple mmap based interface to the card. You'll need to
check lspci -v for the appropriate reg_addr and reg_len variables; the detection
code is quite big to include...

You're looking for a block of non-prefetchable memory exactly 64K in size; this
is from my card:

Memory at ff5f0000 (32-bit, non-prefetchable) [size=64K]
#define _GNU_SOURCE

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int mem_fd = -1;
unsigned int *reg_mem_map = NULL;

/*
 * 05:00.0 VGA compatible controller: ATI Technologies Inc Radeon R350 [Radeon 
9800 Pro] (prog-if 00 [VGA])
 *         Subsystem: ATI Technologies Inc Unknown device 0002
 *         Flags: bus master, stepping, 66MHz, medium devsel, latency 64, IRQ 16
 *         Memory at e8000000 (32-bit, prefetchable) [size=128M]
 *         I/O ports at c800 [size=256]
 *         Memory at ff5f0000 (32-bit, non-prefetchable) [size=64K]
 *         Expansion ROM at ff5c0000 [disabled] [size=128K]
 *         Capabilities: [58] AGP version 3.0
 *         Capabilities: [50] Power Management version 2
 */

unsigned int reg_addr = 0xff5f0000;
unsigned int reg_len = 0x10000;

unsigned int
register_read (unsigned int key)
{
  return reg_mem_map[key >> 2];
}

void
register_write (unsigned int key, unsigned int val)
{
  reg_mem_map[key >> 2] = val;
}

int
main (int argc, char **argv)
{
  if ((mem_fd = open ("/dev/mem", O_RDWR)) < 0)
    {
      fprintf (stderr, "%s: %s:%d: %s\n", program_invocation_short_name,
               __FILE__, __LINE__, strerror (errno));
      exit (EXIT_FAILURE);
    }

  // detect_reg_aperture ();
  if ((reg_mem_map =
       mmap (NULL, reg_len, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd,
             reg_addr)) == MAP_FAILED)
    {
      fprintf (stderr, "%s: %s:%d: %s\n", program_invocation_short_name,
               __FILE__, __LINE__, strerror (errno));
      exit (EXIT_FAILURE);
    }

#if 1

  printf ("0x148 = 0x%08x\n", register_read (0x148));
  register_write (0xdead, 0xbeef);

#endif

  if (munmap (reg_mem_map, reg_len) < 0)
    {
      fprintf (stderr, "%s: %s:%d: %s\n", program_invocation_short_name,
               __FILE__, __LINE__, strerror (errno));
      exit (EXIT_FAILURE);
    }

  if (close (mem_fd) < 0)
    {
      fprintf (stderr, "%s: %s:%d: %s\n", program_invocation_short_name,
               __FILE__, __LINE__, strerror (errno));
      exit (EXIT_FAILURE);
    }

  return 0;
}
-- 
linuxbios mailing list
linuxbios@linuxbios.org
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to