2 * Copyright (C) 2005 Simtec Electronics
3 * Ben Dooks <ben@simtec.co.uk>
5 * Simtec Generic I2C Controller
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
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/delay.h>
25 #include <linux/platform_device.h>
26 #include <linux/slab.h>
28 #include <linux/i2c.h>
29 #include <linux/i2c-algo-bit.h>
33 struct simtec_i2c_data
{
34 struct resource
*ioarea
;
36 struct i2c_adapter adap
;
37 struct i2c_algo_bit_data bit
;
40 #define CMD_SET_SDA (1<<2)
41 #define CMD_SET_SCL (1<<3)
43 #define STATE_SDA (1<<0)
44 #define STATE_SCL (1<<1)
46 /* i2c bit-bus functions */
48 static void simtec_i2c_setsda(void *pw
, int state
)
50 struct simtec_i2c_data
*pd
= pw
;
51 writeb(CMD_SET_SDA
| (state
? STATE_SDA
: 0), pd
->reg
);
54 static void simtec_i2c_setscl(void *pw
, int state
)
56 struct simtec_i2c_data
*pd
= pw
;
57 writeb(CMD_SET_SCL
| (state
? STATE_SCL
: 0), pd
->reg
);
60 static int simtec_i2c_getsda(void *pw
)
62 struct simtec_i2c_data
*pd
= pw
;
63 return readb(pd
->reg
) & STATE_SDA
? 1 : 0;
66 static int simtec_i2c_getscl(void *pw
)
68 struct simtec_i2c_data
*pd
= pw
;
69 return readb(pd
->reg
) & STATE_SCL
? 1 : 0;
72 /* device registration */
74 static int simtec_i2c_probe(struct platform_device
*dev
)
76 struct simtec_i2c_data
*pd
;
81 pd
= kzalloc(sizeof(struct simtec_i2c_data
), GFP_KERNEL
);
83 dev_err(&dev
->dev
, "cannot allocate private data\n");
87 platform_set_drvdata(dev
, pd
);
89 res
= platform_get_resource(dev
, IORESOURCE_MEM
, 0);
91 dev_err(&dev
->dev
, "cannot find IO resource\n");
96 size
= resource_size(res
);
98 pd
->ioarea
= request_mem_region(res
->start
, size
, dev
->name
);
99 if (pd
->ioarea
== NULL
) {
100 dev_err(&dev
->dev
, "cannot request IO\n");
105 pd
->reg
= ioremap(res
->start
, size
);
106 if (pd
->reg
== NULL
) {
107 dev_err(&dev
->dev
, "cannot map IO\n");
112 /* setup the private data */
114 pd
->adap
.owner
= THIS_MODULE
;
115 pd
->adap
.algo_data
= &pd
->bit
;
116 pd
->adap
.dev
.parent
= &dev
->dev
;
118 strlcpy(pd
->adap
.name
, "Simtec I2C", sizeof(pd
->adap
.name
));
121 pd
->bit
.setsda
= simtec_i2c_setsda
;
122 pd
->bit
.setscl
= simtec_i2c_setscl
;
123 pd
->bit
.getsda
= simtec_i2c_getsda
;
124 pd
->bit
.getscl
= simtec_i2c_getscl
;
125 pd
->bit
.timeout
= HZ
;
128 ret
= i2c_bit_add_bus(&pd
->adap
);
138 release_resource(pd
->ioarea
);
146 static int simtec_i2c_remove(struct platform_device
*dev
)
148 struct simtec_i2c_data
*pd
= platform_get_drvdata(dev
);
150 i2c_del_adapter(&pd
->adap
);
153 release_resource(pd
->ioarea
);
163 /* work with hotplug and coldplug */
164 MODULE_ALIAS("platform:simtec-i2c");
166 static struct platform_driver simtec_i2c_driver
= {
168 .name
= "simtec-i2c",
169 .owner
= THIS_MODULE
,
171 .probe
= simtec_i2c_probe
,
172 .remove
= simtec_i2c_remove
,
175 static int __init
i2c_adap_simtec_init(void)
177 return platform_driver_register(&simtec_i2c_driver
);
180 static void __exit
i2c_adap_simtec_exit(void)
182 platform_driver_unregister(&simtec_i2c_driver
);
185 module_init(i2c_adap_simtec_init
);
186 module_exit(i2c_adap_simtec_exit
);
188 MODULE_DESCRIPTION("Simtec Generic I2C Bus driver");
189 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
190 MODULE_LICENSE("GPL");