~ubuntu-branches/debian/sid/flashrom/sid

« back to all changes in this revision

Viewing changes to rayer_spi.c

  • Committer: Package Import Robot
  • Author(s): Uwe Hermann
  • Date: 2012-02-20 11:54:48 UTC
  • mfrom: (1.3.14)
  • Revision ID: package-import@ubuntu.com-20120220115448-53057dgdnwisuhrc
Tags: 0.9.5+r1503-1
* New upstream release.
* debian/docs: Add mysteries_intel.txt.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#if defined(__i386__) || defined(__x86_64__)
32
32
 
33
33
#include <stdlib.h>
 
34
#include <string.h>
34
35
#include "flash.h"
35
36
#include "programmer.h"
36
37
 
 
38
enum rayer_type {
 
39
        TYPE_RAYER,
 
40
        TYPE_XILINX_DLC5,
 
41
};
 
42
 
37
43
/* We have two sets of pins, out and in. The numbers for both sets are
38
44
 * independent and are bitshift values, not real pin numbers.
 
45
 * Default settings are for the RayeR hardware.
39
46
 */
40
47
/* Pins for master->slave direction */
41
 
#define SPI_CS_PIN 5
42
 
#define SPI_SCK_PIN 6
43
 
#define SPI_MOSI_PIN 7
 
48
static int rayer_cs_bit = 5;
 
49
static int rayer_sck_bit = 6;
 
50
static int rayer_mosi_bit = 7;
44
51
/* Pins for slave->master direction */
45
 
#define SPI_MISO_PIN 6
 
52
static int rayer_miso_bit = 6;
46
53
 
47
54
static uint16_t lpt_iobase;
48
55
 
51
58
 
52
59
static void rayer_bitbang_set_cs(int val)
53
60
{
54
 
        lpt_outbyte &= ~(1 << SPI_CS_PIN);
55
 
        lpt_outbyte |= (val << SPI_CS_PIN);
 
61
        lpt_outbyte &= ~(1 << rayer_cs_bit);
 
62
        lpt_outbyte |= (val << rayer_cs_bit);
56
63
        OUTB(lpt_outbyte, lpt_iobase);
57
64
}
58
65
 
59
66
static void rayer_bitbang_set_sck(int val)
60
67
{
61
 
        lpt_outbyte &= ~(1 << SPI_SCK_PIN);
62
 
        lpt_outbyte |= (val << SPI_SCK_PIN);
 
68
        lpt_outbyte &= ~(1 << rayer_sck_bit);
 
69
        lpt_outbyte |= (val << rayer_sck_bit);
63
70
        OUTB(lpt_outbyte, lpt_iobase);
64
71
}
65
72
 
66
73
static void rayer_bitbang_set_mosi(int val)
67
74
{
68
 
        lpt_outbyte &= ~(1 << SPI_MOSI_PIN);
69
 
        lpt_outbyte |= (val << SPI_MOSI_PIN);
 
75
        lpt_outbyte &= ~(1 << rayer_mosi_bit);
 
76
        lpt_outbyte |= (val << rayer_mosi_bit);
70
77
        OUTB(lpt_outbyte, lpt_iobase);
71
78
}
72
79
 
75
82
        uint8_t tmp;
76
83
 
77
84
        tmp = INB(lpt_iobase + 1);
78
 
        tmp = (tmp >> SPI_MISO_PIN) & 0x1;
 
85
        tmp = (tmp >> rayer_miso_bit) & 0x1;
79
86
        return tmp;
80
87
}
81
88
 
85
92
        .set_sck = rayer_bitbang_set_sck,
86
93
        .set_mosi = rayer_bitbang_set_mosi,
87
94
        .get_miso = rayer_bitbang_get_miso,
 
95
        .half_period = 0,
88
96
};
89
97
 
90
98
int rayer_spi_init(void)
91
99
{
92
 
        char *portpos = NULL;
 
100
        char *arg = NULL;
 
101
        enum rayer_type rayer_type = TYPE_RAYER;
93
102
 
94
103
        /* Non-default port requested? */
95
 
        portpos = extract_programmer_param("iobase");
96
 
        if (portpos) {
 
104
        arg = extract_programmer_param("iobase");
 
105
        if (arg) {
97
106
                char *endptr = NULL;
98
107
                unsigned long tmp;
99
 
                tmp = strtoul(portpos, &endptr, 0);
 
108
                tmp = strtoul(arg, &endptr, 0);
100
109
                /* Port 0, port >0x10000, unaligned ports and garbage strings
101
110
                 * are rejected.
102
111
                 */
109
118
                        msg_perr("Error: iobase= specified, but the I/O base "
110
119
                                 "given was invalid.\nIt must be a multiple of "
111
120
                                 "0x4 and lie between 0x100 and 0xfffc.\n");
112
 
                        free(portpos);
 
121
                        free(arg);
113
122
                        return 1;
114
123
                } else {
115
124
                        lpt_iobase = (uint16_t)tmp;
120
129
                /* Pick a default value for the I/O base. */
121
130
                lpt_iobase = 0x378;
122
131
        }
123
 
        free(portpos);
 
132
        free(arg);
124
133
        
125
134
        msg_pdbg("Using address 0x%x as I/O base for parallel port access.\n",
126
135
                 lpt_iobase);
127
136
 
 
137
        arg = extract_programmer_param("type");
 
138
        if (arg) {
 
139
                if (!strcasecmp(arg, "rayer")) {
 
140
                        rayer_type = TYPE_RAYER;
 
141
                } else if (!strcasecmp(arg, "xilinx")) {
 
142
                        rayer_type = TYPE_XILINX_DLC5;
 
143
                } else {
 
144
                        msg_perr("Error: Invalid device type specified.\n");
 
145
                        free(arg);
 
146
                        return 1;
 
147
                }
 
148
        }
 
149
        free(arg);
 
150
        switch (rayer_type) {
 
151
        case TYPE_RAYER:
 
152
                msg_pdbg("Using RayeR SPIPGM pinout.\n");
 
153
                /* Bits for master->slave direction */
 
154
                rayer_cs_bit = 5;
 
155
                rayer_sck_bit = 6;
 
156
                rayer_mosi_bit = 7;
 
157
                /* Bits for slave->master direction */
 
158
                rayer_miso_bit = 6;
 
159
                break;
 
160
        case TYPE_XILINX_DLC5:
 
161
                msg_pdbg("Using Xilinx Parallel Cable III (DLC 5) pinout.\n");
 
162
                /* Bits for master->slave direction */
 
163
                rayer_cs_bit = 2;
 
164
                rayer_sck_bit = 1;
 
165
                rayer_mosi_bit = 0;
 
166
                /* Bits for slave->master direction */
 
167
                rayer_miso_bit = 4;
 
168
        }
 
169
 
128
170
        get_io_perms();
129
171
 
130
172
        /* Get the initial value before writing to any line. */
131
173
        lpt_outbyte = INB(lpt_iobase);
132
174
 
133
 
        /* Zero halfperiod delay. */
134
 
        if (bitbang_spi_init(&bitbang_spi_master_rayer, 0))
 
175
        if (bitbang_spi_init(&bitbang_spi_master_rayer))
135
176
                return 1;
136
177
 
137
178
        return 0;