linux/drivers/staging/rtl8192u/r8180_93cx6.c
<<
>>
Prefs
   1/*
   2 *  This files contains card eeprom (93c46 or 93c56) programming routines,
   3 *  memory is addressed by 16 bits words.
   4 *
   5 *  This is part of rtl8180 OpenSource driver.
   6 *  Copyright (C) Andrea Merello 2004  <andrea.merello@gmail.com>
   7 *  Released under the terms of GPL (General Public Licence)
   8 *
   9 *  Parts of this driver are based on the GPL part of the
  10 *  official realtek driver.
  11 *
  12 *  Parts of this driver are based on the rtl8180 driver skeleton
  13 *  from Patric Schenke & Andres Salomon.
  14 *
  15 *  Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
  16 *
  17 *  We want to thank the Authors of those projects and the Ndiswrapper
  18 *  project Authors.
  19 */
  20
  21#include "r8180_93cx6.h"
  22
  23static void eprom_cs(struct net_device *dev, short bit)
  24{
  25        u8 cmdreg;
  26        int err;
  27
  28        err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
  29        if (err)
  30                return;
  31        if (bit)
  32                /* enable EPROM */
  33                write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CS_BIT);
  34        else
  35                /* disable EPROM */
  36                write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CS_BIT);
  37
  38        force_pci_posting(dev);
  39        udelay(EPROM_DELAY);
  40}
  41
  42
  43static void eprom_ck_cycle(struct net_device *dev)
  44{
  45        u8 cmdreg;
  46        int err;
  47
  48        err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
  49        if (err)
  50                return;
  51        write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CK_BIT);
  52        force_pci_posting(dev);
  53        udelay(EPROM_DELAY);
  54
  55        read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
  56        write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CK_BIT);
  57        force_pci_posting(dev);
  58        udelay(EPROM_DELAY);
  59}
  60
  61
  62static void eprom_w(struct net_device *dev, short bit)
  63{
  64        u8 cmdreg;
  65        int err;
  66
  67        err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
  68        if (err)
  69                return;
  70        if (bit)
  71                write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_W_BIT);
  72        else
  73                write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_W_BIT);
  74
  75        force_pci_posting(dev);
  76        udelay(EPROM_DELAY);
  77}
  78
  79
  80static short eprom_r(struct net_device *dev)
  81{
  82        u8 bit;
  83        int err;
  84
  85        err = read_nic_byte_E(dev, EPROM_CMD, &bit);
  86        if (err)
  87                return err;
  88
  89        udelay(EPROM_DELAY);
  90
  91        if (bit & EPROM_R_BIT)
  92                return 1;
  93
  94        return 0;
  95}
  96
  97
  98static void eprom_send_bits_string(struct net_device *dev, short b[], int len)
  99{
 100        int i;
 101
 102        for (i = 0; i < len; i++) {
 103                eprom_w(dev, b[i]);
 104                eprom_ck_cycle(dev);
 105        }
 106}
 107
 108
 109int eprom_read(struct net_device *dev, u32 addr)
 110{
 111        struct r8192_priv *priv = ieee80211_priv(dev);
 112        short read_cmd[] = {1, 1, 0};
 113        short addr_str[8];
 114        int i;
 115        int addr_len;
 116        u32 ret;
 117        int err;
 118
 119        ret = 0;
 120        /* enable EPROM programming */
 121        write_nic_byte_E(dev, EPROM_CMD,
 122                       (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
 123        force_pci_posting(dev);
 124        udelay(EPROM_DELAY);
 125
 126        if (priv->epromtype == EPROM_93c56) {
 127                addr_str[7] = addr & 1;
 128                addr_str[6] = addr & (1<<1);
 129                addr_str[5] = addr & (1<<2);
 130                addr_str[4] = addr & (1<<3);
 131                addr_str[3] = addr & (1<<4);
 132                addr_str[2] = addr & (1<<5);
 133                addr_str[1] = addr & (1<<6);
 134                addr_str[0] = addr & (1<<7);
 135                addr_len = 8;
 136        } else {
 137                addr_str[5] = addr & 1;
 138                addr_str[4] = addr & (1<<1);
 139                addr_str[3] = addr & (1<<2);
 140                addr_str[2] = addr & (1<<3);
 141                addr_str[1] = addr & (1<<4);
 142                addr_str[0] = addr & (1<<5);
 143                addr_len = 6;
 144        }
 145        eprom_cs(dev, 1);
 146        eprom_ck_cycle(dev);
 147        eprom_send_bits_string(dev, read_cmd, 3);
 148        eprom_send_bits_string(dev, addr_str, addr_len);
 149
 150        /*
 151         * keep chip pin D to low state while reading.
 152         * I'm unsure if it is necessary, but anyway shouldn't hurt
 153         */
 154        eprom_w(dev, 0);
 155
 156        for (i = 0; i < 16; i++) {
 157                /* eeprom needs a clk cycle between writing opcode&adr
 158                 * and reading data. (eeprom outs a dummy 0)
 159                 */
 160                eprom_ck_cycle(dev);
 161                err = eprom_r(dev);
 162                if (err < 0)
 163                        return err;
 164
 165                ret |= err<<(15-i);
 166        }
 167
 168        eprom_cs(dev, 0);
 169        eprom_ck_cycle(dev);
 170
 171        /* disable EPROM programming */
 172        write_nic_byte_E(dev, EPROM_CMD,
 173                       (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
 174        return ret;
 175}
 176