OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [i2c/] [i2c-algo-sibyte.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* ------------------------------------------------------------------------- */
2
/* i2c-algo-sibyte.c i2c driver algorithms for bit-shift adapters                    */
3
/* ------------------------------------------------------------------------- */
4
/*   Copyright (C) 2001,2002,2003 Broadcom Corporation
5
     Copyright (C) 1995-2000 Simon G. Vogl
6
 
7
    This program is free software; you can redistribute it and/or modify
8
    it under the terms of the GNU General Public License as published by
9
    the Free Software Foundation; either version 2 of the License, or
10
    (at your option) any later version.
11
 
12
    This program is distributed in the hope that it will be useful,
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
    GNU General Public License for more details.
16
 
17
    You should have received a copy of the GNU General Public License
18
    along with this program; if not, write to the Free Software
19
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
20
/* ------------------------------------------------------------------------- */
21
 
22
/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
23
   Frodo Looijaard <frodol@dds.nl>.  */
24
 
25
/* Ported for SiByte SOCs by Broadcom Corporation.  */
26
 
27
#include <linux/config.h>
28
#include <linux/kernel.h>
29
#include <linux/module.h>
30
#include <linux/init.h>
31
 
32
#include <asm/sibyte/64bit.h>
33
#include <asm/sibyte/sb1250_regs.h>
34
#include <asm/sibyte/sb1250_smbus.h>
35
 
36
#include <linux/i2c.h>
37
#include <linux/i2c-algo-sibyte.h>
38
 
39
/* ----- global defines ----------------------------------------------- */
40
#define SMB_CSR(a,r) ((long)(a->reg_base + r))
41
 
42
/* ----- global variables --------------------------------------------- */
43
 
44
/* module parameters:
45
 */
46
static int bit_scan=0;   /* have a look at what's hanging 'round         */
47
 
48
 
49
static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr,
50
                      unsigned short flags, char read_write,
51
                      u8 command, int size, union i2c_smbus_data * data)
52
{
53
        struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data;
54
        int data_bytes = 0;
55
        int error;
56
 
57
        while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY)
58
                ;
59
 
60
        switch (size) {
61
        case I2C_SMBUS_QUICK:
62
                csr_out32((V_SMB_ADDR(addr) | (read_write == I2C_SMBUS_READ ? M_SMB_QDATA : 0) |
63
                           V_SMB_TT_QUICKCMD), SMB_CSR(adap, R_SMB_START));
64
                break;
65
        case I2C_SMBUS_BYTE:
66
                if (read_write == I2C_SMBUS_READ) {
67
                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_RD1BYTE),
68
                                  SMB_CSR(adap, R_SMB_START));
69
                        data_bytes = 1;
70
                } else {
71
                        csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD));
72
                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR1BYTE),
73
                                  SMB_CSR(adap, R_SMB_START));
74
                }
75
                break;
76
        case I2C_SMBUS_BYTE_DATA:
77
                csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD));
78
                if (read_write == I2C_SMBUS_READ) {
79
                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_CMD_RD1BYTE),
80
                                  SMB_CSR(adap, R_SMB_START));
81
                        data_bytes = 1;
82
                } else {
83
                        csr_out32(V_SMB_LB(data->byte), SMB_CSR(adap, R_SMB_DATA));
84
                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE),
85
                                  SMB_CSR(adap, R_SMB_START));
86
                }
87
                break;
88
        case I2C_SMBUS_WORD_DATA:
89
                csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD));
90
                if (read_write == I2C_SMBUS_READ) {
91
                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_CMD_RD2BYTE),
92
                                  SMB_CSR(adap, R_SMB_START));
93
                        data_bytes = 2;
94
                } else {
95
                        csr_out32(V_SMB_LB(data->word & 0xff), SMB_CSR(adap, R_SMB_DATA));
96
                        csr_out32(V_SMB_MB(data->word >> 8), SMB_CSR(adap, R_SMB_DATA));
97
                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE),
98
                                  SMB_CSR(adap, R_SMB_START));
99
                }
100
                break;
101
        default:
102
                return -1;      /* XXXKW better error code? */
103
        }
104
 
105
        while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY)
106
                ;
107
 
108
        error = csr_in32(SMB_CSR(adap, R_SMB_STATUS));
109
        if (error & M_SMB_ERROR) {
110
                /* Clear error bit by writing a 1 */
111
                csr_out32(M_SMB_ERROR, SMB_CSR(adap, R_SMB_STATUS));
112
                return -1;      /* XXXKW better error code? */
113
        }
114
 
115
        if (data_bytes == 1)
116
                data->byte = csr_in32(SMB_CSR(adap, R_SMB_DATA)) & 0xff;
117
        if (data_bytes == 2)
118
                data->word = csr_in32(SMB_CSR(adap, R_SMB_DATA)) & 0xffff;
119
 
120
        return 0;
121
}
122
 
123
static int algo_control(struct i2c_adapter *adapter,
124
        unsigned int cmd, unsigned long arg)
125
{
126
        return 0;
127
}
128
 
129
static u32 bit_func(struct i2c_adapter *adap)
130
{
131
        return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
132
                I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA);
133
}
134
 
135
 
136
/* -----exported algorithm data: -------------------------------------  */
137
 
138
static struct i2c_algorithm i2c_sibyte_algo = {
139
        "SiByte algorithm",
140
        I2C_ALGO_SIBYTE,
141
        NULL,                           /* master_xfer          */
142
        smbus_xfer,                     /* smbus_xfer           */
143
        NULL,                           /* slave_xmit           */
144
        NULL,                           /* slave_recv           */
145
        algo_control,                   /* ioctl                */
146
        bit_func,                       /* functionality        */
147
};
148
 
149
/*
150
 * registering functions to load algorithms at runtime
151
 */
152
int i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)
153
{
154
        int i;
155
        struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data;
156
 
157
        /* register new adapter to i2c module... */
158
 
159
        i2c_adap->id |= i2c_sibyte_algo.id;
160
        i2c_adap->algo = &i2c_sibyte_algo;
161
 
162
        /* Set the frequency to 100 kHz */
163
        csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ));
164
        csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL));
165
 
166
        /* scan bus */
167
        if (bit_scan) {
168
                union i2c_smbus_data data;
169
                int rc;
170
                printk(KERN_INFO " i2c-algo-sibyte.o: scanning bus %s.\n",
171
                       i2c_adap->name);
172
                for (i = 0x00; i < 0x7f; i++) {
173
                        /* XXXKW is this a realistic probe? */
174
                        rc = smbus_xfer(i2c_adap, i, 0, I2C_SMBUS_READ, 0,
175
                                        I2C_SMBUS_BYTE_DATA, &data);
176
                        if (!rc) {
177
                                printk("(%02x)",i);
178
                        } else
179
                                printk(".");
180
                }
181
                printk("\n");
182
        }
183
 
184
#ifdef MODULE
185
        MOD_INC_USE_COUNT;
186
#endif
187
        i2c_add_adapter(i2c_adap);
188
 
189
        return 0;
190
}
191
 
192
 
193
int i2c_sibyte_del_bus(struct i2c_adapter *adap)
194
{
195
        int res;
196
 
197
        if ((res = i2c_del_adapter(adap)) < 0)
198
                return res;
199
 
200
#ifdef MODULE
201
        MOD_DEC_USE_COUNT;
202
#endif
203
        return 0;
204
}
205
 
206
int __init i2c_algo_sibyte_init (void)
207
{
208
        printk("i2c-algo-sibyte.o: i2c SiByte algorithm module\n");
209
        return 0;
210
}
211
 
212
 
213
EXPORT_SYMBOL(i2c_sibyte_add_bus);
214
EXPORT_SYMBOL(i2c_sibyte_del_bus);
215
 
216
#ifdef MODULE
217
MODULE_AUTHOR("Kip Walker, Broadcom Corp.");
218
MODULE_DESCRIPTION("SiByte I2C-Bus algorithm");
219
MODULE_PARM(bit_scan, "i");
220
MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus");
221
MODULE_LICENSE("GPL");
222
 
223
int init_module(void)
224
{
225
        return i2c_algo_sibyte_init();
226
}
227
 
228
void cleanup_module(void)
229
{
230
}
231
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.