1 #include <linux/module.h>
2 #include <linux/errno.h>
3 #include <linux/signal.h>
4 #include <linux/sched.h>
5 #include <linux/timer.h>
6 #include <linux/interrupt.h>
7 #include <linux/string.h>
8 #include <linux/fcntl.h>
9 #include <linux/ptrace.h>
10 //#include <linux/cyclades.h>
12 #include <linux/ioport.h>
13 #include <linux/init.h>
14 #include <linux/delay.h>
15 #include <linux/spinlock.h>
16 #include <linux/bitops.h>
17 #include <linux/proc_fs.h>
19 #include <asm/system.h>
22 #include <asm/uaccess.h>
24 #include <linux/types.h>
25 #include <linux/kernel.h>
26 #include <linux/pci.h>
28 #define DEV_NAME "i2c_spd"
31 #define I2C_STATUS 0x18
39 struct i2c_spd_info_t
{
41 struct pci_dev
*pcidev
;
43 struct i2c_dev adrdev
[256];
44 void __iomem
*base_io
;
45 struct proc_dir_entry
*proc_dev
;
52 static int i2c_spd_probe(struct pci_dev
*pcidev
,
53 const struct pci_device_id
*pciid
);
54 static void i2c_spd_remove(struct pci_dev
*pci_dev
);
55 inline int i2c_read_reg(struct pci_dev
*dev
, char *base
, unsigned char reg
,
57 inline int i2c_write_reg(struct pci_dev
*dev
, char *base
, unsigned char reg
,
61 static int proc_read_i2c_spd(char *page
, char **start
,
62 off_t off
, int count
, int *eof
, void *data
)
65 struct i2c_spd_info_t
*device
= (struct i2c_spd_info_t
*)data
;
66 struct pci_dev
*dev
= device
->pcidev
;
71 spin_lock(&device
->spd_lock
);
72 for (i
= 0; i
< device
->count
; i
++) {
73 bus
= device
->adrdev
[i
].bus
;
74 adr
= device
->adrdev
[i
]._addr
;
75 len
+= sprintf(&page
[len
], "Module %d", i
);
77 for (j
= 0; j
< SPD_SZ
; j
++) {
79 len
+= sprintf(&page
[len
], "\n\t");
80 if (i2c_read_reg(dev
, &dt
, j
, bus
, adr
) <= 0) { // read status reg
81 len
= sprintf(page
, "Error read spd unit\n");
84 len
+= sprintf(&page
[len
], "%02x ", dt
);
86 len
+= sprintf(&page
[len
], "\n\n");
89 spin_unlock(&device
->spd_lock
);
93 int i2c_base_write(struct pci_dev
*dev
, char *base
, int sz
, int bus
, int adr
,
96 struct i2c_spd_info_t
*device
= pci_get_drvdata(dev
);
98 volatile u32 i2c_ctrl
=
99 0x1 | (sz
<< 1) | (adr
<< 15) | (bus
<< 24) | (0 << 26) | (1 << 28)
100 | (reg
<< 7) | (0 << 22) | (1 << 23);
101 // write | size | 7bit addr | 0 -phase data | bus number | start byte on | start
102 volatile u32 i2c_mode
= 0;
107 for (i
= 1000000; i
; i
--) {
108 if (readl(device
->dev
+ I2C_STATUS
) & 0x1) {
118 for (k
= 0; k
< sz
; k
++) {
119 writeb(*(base
+ k
), device
->base_io
+ k
);
122 writel(i2c_mode
, device
->dev
+ I2C_MODE
);
123 writel(0x1e, device
->dev
+ I2C_STATUS
);
124 writel(i2c_ctrl
, device
->dev
+ I2C_CTRL
);
128 for (i
= 1000000; i
; i
--) {
129 ret
= readl(device
->dev
+ I2C_STATUS
);
134 if (ret
& 0x2 && (!(ret
& 0x1c))) {
143 writel((1 << 27), device
->dev
+ I2C_CTRL
); //kill task
144 writel(0x1e, device
->dev
+ I2C_STATUS
); //clean error bits
150 int i2c_base_read(struct pci_dev
*dev
, char *base
, int sz
, int bus
, int adr
,
154 struct i2c_spd_info_t
*device
= pci_get_drvdata(dev
);
155 // sz < 63 //0x1 | (sz << 1) | (adr << 15) | (bus << 24) | (0 << 26) | (1 << 28) | (reg << 7) | (0 << 22) | (1 << 23);
156 volatile u32 i2c_ctrl
=
157 0x0 | (sz
<< 1) | (adr
<< 15) | (bus
<< 24) | (0 << 26) | (1 << 28)
158 | (reg
<< 7) | (1 << 23) | (0 << 22);
159 volatile u32 i2c_mode
= 0;
164 // start transfer data
166 for (i
= 1000000; i
; i
--) {
167 if (readl(device
->dev
+ I2C_STATUS
) & 0x1) {
177 writel(i2c_mode
, device
->dev
+ I2C_MODE
);
178 writel(0x1e, device
->dev
+ I2C_STATUS
);
180 writel(i2c_ctrl
, device
->dev
+ I2C_CTRL
);
184 for (i
= 1000000; i
; i
--) {
185 ret
= readl(device
->dev
+ I2C_STATUS
);
191 if (ret
& 0x2 && (!(ret
& 0x1c))) {
194 for (j
= 0; j
< sz
; j
++) {
195 char b
= readb(device
->base_io
+ j
);
206 writel((i2c_ctrl
= (1 << 27)), device
->dev
+ I2C_CTRL
);
207 writel(0x1e, device
->dev
+ I2C_STATUS
); //clean error bits
214 inline int i2c_read_reg(struct pci_dev
*dev
, char *base
, unsigned char reg
,
217 int ret
= i2c_base_write(dev
, ®
, 1, bus
, adr
, 00);
222 return i2c_base_read(dev
, base
, 1, bus
, adr
, 00);
225 inline int i2c_write_reg(struct pci_dev
*dev
, char *base
, unsigned char reg
,
231 return i2c_base_write(dev
, &ctm
[0], 2, bus
, adr
, 00);
234 static int i2c_find_spd_dev(struct i2c_spd_info_t
*device
)
237 struct pci_dev
*pcidev
= device
->pcidev
;
241 for (j
= 0; j
< 1; j
++) {
242 for (f
= 0; f
< 8; f
++) {
243 if (i2c_read_reg(pcidev
, &ctm
[0], 0, j
, adr
+ f
) > 0) {
244 printk("spd chip found at %d:%x\n",j
, adr
+ f
);
245 device
->adrdev
[k
].bus
= j
;
246 device
->adrdev
[k
]._addr
= adr
+ f
;
255 static int i2c_spd_probe(struct pci_dev
*pcidev
,
256 const struct pci_device_id
*pciid
)
258 struct i2c_spd_info_t
*device
;
259 static char fflag
= 0;
262 (struct i2c_spd_info_t
*)kmalloc(sizeof(struct i2c_spd_info_t
),
264 if (device
== NULL
) {
265 printk(KERN_ALERT
"I2C - Error while trying alloc memory.\n");
268 memset(device
, 0, sizeof(struct i2c_spd_info_t
));
270 memset(device
->adrdev
, -1, sizeof(struct i2c_dev
) * 256);
272 device
->pcidev
= pcidev
;
273 spin_lock_init(&device
->spd_lock
);
276 device
->dev
= pci_iomap(device
->pcidev
, 0, 0);
277 device
->base_io
= pci_iomap(device
->pcidev
, 1, 0);
279 pci_set_drvdata(pcidev
, device
);
282 device
->count
= i2c_find_spd_dev(device
);
284 if (device
->count
== 0)
287 printk("%d spd chips was found\n", device
->count
);
289 device
->proc_dev
= create_proc_entry("i2c_spd", 0444, NULL
);
290 if (device
->proc_dev
== NULL
) {
293 strcpy((char *)device
->proc_dev
->name
, "i2c_spd");
294 device
->proc_dev
->data
= device
;
295 device
->proc_dev
->read_proc
= proc_read_i2c_spd
;
296 device
->proc_dev
->write_proc
= NULL
;
303 pci_set_drvdata(pcidev
, NULL
);
309 static int __init
i2c_spd_init_module(void)
312 struct pci_dev
*dev
= NULL
;
315 dev
= pci_get_device(0x8086, 0x0002, dev
);
317 if (i2c_spd_probe(dev
, NULL
) == 0)
320 } while (dev
!= NULL
);
323 printk ("i2c_spd: Unable to locate any i2c_spd"
324 " device with valid IDs\n");
331 static void i2c_spd_remove(struct pci_dev
*pci_dev1
)
333 struct i2c_spd_info_t
*device
; // = pci_get_drvdata(pci_dev);
334 struct pci_dev
*pcidev
= 0; // = device->pcidev;
337 pcidev
= pci_get_device(0x8086, 0x0002, pcidev
);
339 device
= pci_get_drvdata(pcidev
);
340 pci_set_drvdata(pcidev
, NULL
);
341 remove_proc_entry("i2c_spd", device
->proc_dev
);
342 pci_iounmap(pcidev
, device
->dev
);
343 pci_iounmap(pcidev
, device
->base_io
);
346 } while (pcidev
!= NULL
);
349 static void i2c_spd_exit_module(void)
351 i2c_spd_remove(NULL
);
354 module_init(i2c_spd_init_module
);
355 module_exit(i2c_spd_exit_module
);
357 MODULE_DESCRIPTION("I2C Driver for dumping spd");
358 MODULE_LICENSE("GPL");